Check-in [00d59d6925]
Not logged in

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

Overview
Comment:update DiffUtilTcl to version 0.4.1
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 00d59d69252746c8b527424f252933c99df59ad9
User & Date: chw 2019-06-13 12:53:13
Context
2019-06-13
12:54
improve twv demo check-in: b9d5c5a105 user: chw tags: trunk
12:53
update DiffUtilTcl to version 0.4.1 check-in: 00d59d6925 user: chw tags: trunk
10:46
improve twv demo, again check-in: 3e88960bb1 user: chw tags: trunk
Changes

Changes to undroid/DiffUtilTcl/ChangeLog.

            1  +2019-03-27  Peter Spjuth  <peter.spjuth@gmail.com>
            2  +	Always allow post processing for small blocks.
            3  +
            4  +2018-10-07  Peter Spjuth  <peter.spjuth@gmail.com>
            5  +	Bumped revision to 0.4.1
            6  +	Working compareStreams command.
            7  +
            8  +2018-10-06  Peter Spjuth  <peter.spjuth@gmail.com>
            9  +	Started on compareStreams command.
           10  +
     1     11   2017-12-02  Peter Spjuth  <peter.spjuth@gmail.com>
     2     12   	Bumped revision to 0.4.0
     3     13   	Require Tcl 8.6.
     4     14   
     5     15   2017-12-02  Peter Spjuth  <peter.spjuth@gmail.com>
     6     16   	Bumped revision to 0.3.11
     7     17   	Changed default pivot to 10.
................................................................................
    55     65   
    56     66   2012-07-10  Peter Spjuth  <peter.spjuth@gmail.com>
    57     67   	Lots of restructuring to allow LcsCore to work recursively.
    58     68   	Specially, all lines are included in V/E/P vectors even if
    59     69   	a range is set.
    60     70   
    61     71   2012-07-02  Peter Spjuth  <peter.spjuth@gmail.com>
    62         -	Handle alignment withing postprocessing of forbidden matches.
           72  +	Handle alignment within postprocessing of forbidden matches.
    63     73   
    64     74   2012-06-26  Peter Spjuth  <peter.spjuth@gmail.com>
    65     75   	Bug-fix in postprocessing of forbidden lines.
    66     76   
    67     77   2012-06-26  Peter Spjuth  <peter.spjuth@gmail.com>
    68     78   	Bumped revision to 0.3.6
    69     79   

Changes to undroid/DiffUtilTcl/RevisionBump.txt.

     1      1   The following files contain current revision and needs to be changed
     2      2   when bumping revisions:
     3      3   configure.ac     (AC_INIT)
     4      4   doc/diffutil.man (two places)
     5      5   tcl/diffutil.tcl (package provide)
     6         -win/makefile.vc  (DOTVERSION)
     7      6   
     8      7   Then rerun
     9      8   autoconf
    10      9   configure
    11     10   make clean
    12     11   make
    13     12   make vfs

Changes to undroid/DiffUtilTcl/configure.

     1      1   #! /bin/sh
     2      2   # Guess values for system-dependent variables and create Makefiles.
     3         -# Generated by GNU Autoconf 2.63 for DiffUtil 0.4.0.
            3  +# Generated by GNU Autoconf 2.63 for DiffUtil 0.4.1.
     4      4   #
     5      5   # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
     6      6   # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
     7      7   # This configure script is free software; the Free Software Foundation
     8      8   # gives unlimited permission to copy, distribute and modify it.
     9      9   ## --------------------- ##
    10     10   ## M4sh Initialization.  ##
................................................................................
   590    590   MFLAGS=
   591    591   MAKEFLAGS=
   592    592   SHELL=${CONFIG_SHELL-/bin/sh}
   593    593   
   594    594   # Identity of this package.
   595    595   PACKAGE_NAME='DiffUtil'
   596    596   PACKAGE_TARNAME='diffutil'
   597         -PACKAGE_VERSION='0.4.0'
   598         -PACKAGE_STRING='DiffUtil 0.4.0'
          597  +PACKAGE_VERSION='0.4.1'
          598  +PACKAGE_STRING='DiffUtil 0.4.1'
   599    599   PACKAGE_BUGREPORT=''
   600    600   
   601    601   # Factoring default headers for most tests.
   602    602   ac_includes_default="\
   603    603   #include <stdio.h>
   604    604   #ifdef HAVE_SYS_TYPES_H
   605    605   # include <sys/types.h>
................................................................................
  1315   1315   #
  1316   1316   # Report the --help message.
  1317   1317   #
  1318   1318   if test "$ac_init_help" = "long"; then
  1319   1319     # Omit some internal or obsolete options to make the list less imposing.
  1320   1320     # This message is too long to be a string in the A/UX 3.1 sh.
  1321   1321     cat <<_ACEOF
  1322         -\`configure' configures DiffUtil 0.4.0 to adapt to many kinds of systems.
         1322  +\`configure' configures DiffUtil 0.4.1 to adapt to many kinds of systems.
  1323   1323   
  1324   1324   Usage: $0 [OPTION]... [VAR=VALUE]...
  1325   1325   
  1326   1326   To assign environment variables (e.g., CC, CFLAGS...), specify them as
  1327   1327   VAR=VALUE.  See below for descriptions of some of the useful variables.
  1328   1328   
  1329   1329   Defaults for the options are specified in brackets.
................................................................................
  1376   1376   
  1377   1377     cat <<\_ACEOF
  1378   1378   _ACEOF
  1379   1379   fi
  1380   1380   
  1381   1381   if test -n "$ac_init_help"; then
  1382   1382     case $ac_init_help in
  1383         -     short | recursive ) echo "Configuration of DiffUtil 0.4.0:";;
         1383  +     short | recursive ) echo "Configuration of DiffUtil 0.4.1:";;
  1384   1384      esac
  1385   1385     cat <<\_ACEOF
  1386   1386   
  1387   1387   Optional Features:
  1388   1388     --disable-option-checking  ignore unrecognized --enable/--with options
  1389   1389     --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  1390   1390     --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
................................................................................
  1475   1475       cd "$ac_pwd" || { ac_status=$?; break; }
  1476   1476     done
  1477   1477   fi
  1478   1478   
  1479   1479   test -n "$ac_init_help" && exit $ac_status
  1480   1480   if $ac_init_version; then
  1481   1481     cat <<\_ACEOF
  1482         -DiffUtil configure 0.4.0
         1482  +DiffUtil configure 0.4.1
  1483   1483   generated by GNU Autoconf 2.63
  1484   1484   
  1485   1485   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
  1486   1486   2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
  1487   1487   This configure script is free software; the Free Software Foundation
  1488   1488   gives unlimited permission to copy, distribute and modify it.
  1489   1489   _ACEOF
  1490   1490     exit
  1491   1491   fi
  1492   1492   cat >config.log <<_ACEOF
  1493   1493   This file contains any messages produced by compilers while
  1494   1494   running configure, to aid debugging if configure makes a mistake.
  1495   1495   
  1496         -It was created by DiffUtil $as_me 0.4.0, which was
         1496  +It was created by DiffUtil $as_me 0.4.1, which was
  1497   1497   generated by GNU Autoconf 2.63.  Invocation command line was
  1498   1498   
  1499   1499     $ $0 $@
  1500   1500   
  1501   1501   _ACEOF
  1502   1502   exec 5>>config.log
  1503   1503   {
................................................................................
 12520  12520   
 12521  12521   exec 6>&1
 12522  12522   
 12523  12523   # Save the log message, to keep $[0] and so on meaningful, and to
 12524  12524   # report actual input values of CONFIG_FILES etc. instead of their
 12525  12525   # values after options handling.
 12526  12526   ac_log="
 12527         -This file was extended by DiffUtil $as_me 0.4.0, which was
        12527  +This file was extended by DiffUtil $as_me 0.4.1, which was
 12528  12528   generated by GNU Autoconf 2.63.  Invocation command line was
 12529  12529   
 12530  12530     CONFIG_FILES    = $CONFIG_FILES
 12531  12531     CONFIG_HEADERS  = $CONFIG_HEADERS
 12532  12532     CONFIG_LINKS    = $CONFIG_LINKS
 12533  12533     CONFIG_COMMANDS = $CONFIG_COMMANDS
 12534  12534     $ $0 $@
................................................................................
 12570  12570   $config_files
 12571  12571   
 12572  12572   Report bugs to <bug-autoconf@gnu.org>."
 12573  12573   
 12574  12574   _ACEOF
 12575  12575   cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 12576  12576   ac_cs_version="\\
 12577         -DiffUtil config.status 0.4.0
        12577  +DiffUtil config.status 0.4.1
 12578  12578   configured by $0, generated by GNU Autoconf 2.63,
 12579  12579     with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 12580  12580   
 12581  12581   Copyright (C) 2008 Free Software Foundation, Inc.
 12582  12582   This config.status script is free software; the Free Software Foundation
 12583  12583   gives unlimited permission to copy, distribute and modify it."
 12584  12584   

Changes to undroid/DiffUtilTcl/configure.ac.

    15     15   # This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION
    16     16   # set as provided.  These will also be added as -D defs in your Makefile
    17     17   # so you can encode the package version directly into the source files.
    18     18   # This will also define a special symbol for Windows (BUILD_<PACKAGE_NAME>
    19     19   # so that we create the export library with the dll.
    20     20   #-----------------------------------------------------------------------
    21     21   
    22         -AC_INIT([DiffUtil], [0.4.0])
           22  +AC_INIT([DiffUtil], [0.4.1])
    23     23   
    24     24   #--------------------------------------------------------------------
    25     25   # Call TEA_INIT as the first TEA_ macro to set up initial vars.
    26     26   # This will define a ${TEA_PLATFORM} variable == "unix" or "windows"
    27     27   # as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE.
    28     28   #--------------------------------------------------------------------
    29     29   

Changes to undroid/DiffUtilTcl/doc/diffutil.html.

     1         -<html><head>
            1  +<!DOCTYPE html><html><head>
     2      2   <title>DiffUtil - Comparision Utilities</title>
     3      3   <style type="text/css"><!--
     4      4       HTML {
     5      5   	background: 	#FFFFFF;
     6      6   	color: 		black;
     7      7       }
     8      8       BODY {
................................................................................
    20     20   	margin-top: 	1em;
    21     21   	font-family:	sans-serif;
    22     22   	font-size:	large;
    23     23   	color:		#005A9C;
    24     24   	background: 	transparent;
    25     25   	text-align:		left;
    26     26       }
    27         -    H1.title {
           27  +    H1.doctools_title {
    28     28   	text-align: center;
    29     29       }
    30     30       UL,OL {
    31     31   	margin-right: 0em;
    32     32   	margin-top: 3pt;
    33     33   	margin-bottom: 3pt;
    34     34       }
................................................................................
    37     37       }
    38     38       OL LI {
    39     39   	list-style: decimal;
    40     40       }
    41     41       DT {
    42     42   	padding-top: 	1ex;
    43     43       }
    44         -    UL.toc,UL.toc UL, UL.toc UL UL {
           44  +    UL.doctools_toc,UL.doctools_toc UL, UL.doctools_toc UL UL {
    45     45   	font:		normal 12pt/14pt sans-serif;
    46     46   	list-style:	none;
    47     47       }
    48         -    LI.section, LI.subsection {
           48  +    LI.doctools_section, LI.doctools_subsection {
    49     49   	list-style: 	none;
    50     50   	margin-left: 	0em;
    51     51   	text-indent:	0em;
    52     52   	padding: 	0em;
    53     53       }
    54     54       PRE {
    55     55   	display: 	block;
................................................................................
    58     58   	margin:		0%;
    59     59   	padding-top:	0.5ex;
    60     60   	padding-bottom:	0.5ex;
    61     61   	padding-left:	1ex;
    62     62   	padding-right:	1ex;
    63     63   	width:		100%;
    64     64       }
    65         -    PRE.example {
           65  +    PRE.doctools_example {
    66     66   	color: 		black;
    67     67   	background: 	#f5dcb3;
    68     68   	border:		1px solid black;
    69     69       }
    70         -    UL.requirements LI, UL.syntax LI {
           70  +    UL.doctools_requirements LI, UL.doctools_syntax LI {
    71     71   	list-style: 	none;
    72     72   	margin-left: 	0em;
    73     73   	text-indent:	0em;
    74     74   	padding:	0em;
    75     75       }
    76         -    DIV.synopsis {
           76  +    DIV.doctools_synopsis {
    77     77   	color: 		black;
    78     78   	background: 	#80ffff;
    79     79   	border:		1px solid black;
    80     80   	font-family:	serif;
    81     81   	margin-top: 	1em;
    82     82   	margin-bottom: 	1em;
    83     83       }
    84         -    UL.syntax {
           84  +    UL.doctools_syntax {
    85     85   	margin-top: 	1em;
    86     86   	border-top:	1px solid black;
    87     87       }
    88         -    UL.requirements {
           88  +    UL.doctools_requirements {
    89     89   	margin-bottom: 	1em;
    90     90   	border-bottom:	1px solid black;
    91     91       }
    92     92   --></style>
    93     93   </head>
    94         -<! -- Generated from file 'diffutil.man' by tcllib/doctools with format 'html'
           94  +<!-- Generated from file 'diffutil.man' by tcllib/doctools with format 'html'
    95     95      -->
    96         -<! -- Copyright &copy; 2010, Peter Spjuth
           96  +<!-- Copyright &amp;copy; 2010, Peter Spjuth
    97     97      -->
    98         -<! -- CVS: $Id$ DiffUtil.n
           98  +<!-- DiffUtil.n
    99     99      -->
   100    100   <body><div class="doctools">
   101         -<h1 class="title">DiffUtil(n) 0.4.0 diffutil &quot;Comparision Utilities&quot;</h1>
   102         -<div id="name" class="section"><h2><a name="name">Name</a></h2>
          101  +<h1 class="doctools_title">DiffUtil(n) 0.4.1 diffutil &quot;Comparision Utilities&quot;</h1>
          102  +<div id="name" class="doctools_section"><h2><a name="name">Name</a></h2>
   103    103   <p>DiffUtil - Compare Stuff</p>
   104    104   </div>
   105         -<div id="toc" class="section"><h2><a name="toc">Table Of Contents</a></h2>
   106         -<ul class="toc">
   107         -<li class="section"><a href="#toc">Table Of Contents</a></li>
   108         -<li class="section"><a href="#synopsis">Synopsis</a></li>
   109         -<li class="section"><a href="#section1">Description</a></li>
   110         -<li class="section"><a href="#section2">COMMANDS</a></li>
   111         -<li class="section"><a href="#section3">EXAMPLES</a></li>
   112         -<li class="section"><a href="#keywords">Keywords</a></li>
   113         -<li class="section"><a href="#copyright">Copyright</a></li>
          105  +<div id="toc" class="doctools_section"><h2><a name="toc">Table Of Contents</a></h2>
          106  +<ul class="doctools_toc">
          107  +<li class="doctools_section"><a href="#toc">Table Of Contents</a></li>
          108  +<li class="doctools_section"><a href="#synopsis">Synopsis</a></li>
          109  +<li class="doctools_section"><a href="#section1">Description</a></li>
          110  +<li class="doctools_section"><a href="#section2">COMMANDS</a></li>
          111  +<li class="doctools_section"><a href="#section3">EXAMPLES</a></li>
          112  +<li class="doctools_section"><a href="#keywords">Keywords</a></li>
          113  +<li class="doctools_section"><a href="#copyright">Copyright</a></li>
   114    114   </ul>
   115    115   </div>
   116         -<div id="synopsis" class="section"><h2><a name="synopsis">Synopsis</a></h2>
   117         -<div class="synopsis">
   118         -<ul class="requirements">
          116  +<div id="synopsis" class="doctools_section"><h2><a name="synopsis">Synopsis</a></h2>
          117  +<div class="doctools_synopsis">
          118  +<ul class="doctools_requirements">
   119    119   <li>package require <b class="pkgname">Tcl 8.6</b></li>
   120         -<li>package require <b class="pkgname">DiffUtil <span class="opt">?0.4.0?</span></b></li>
          120  +<li>package require <b class="pkgname">DiffUtil <span class="opt">?0.4.1?</span></b></li>
   121    121   </ul>
   122         -<ul class="syntax">
          122  +<ul class="doctools_syntax">
   123    123   <li><a href="#1"><b class="cmd">::DiffUtil::diffFiles</b> <span class="opt">?<i class="arg">options</i>?</span> <i class="arg">file1</i> <i class="arg">file2</i></a></li>
   124    124   <li><a href="#2"><b class="cmd">::DiffUtil::diffLists</b> <span class="opt">?<i class="arg">options</i>?</span> <i class="arg">list1</i> <i class="arg">list2</i></a></li>
          125  +<li><a href="#3"><b class="cmd">::DiffUtil::compareFiles</b> <span class="opt">?<i class="arg">options</i>?</span> <i class="arg">file1</i> <i class="arg">file2</i></a></li>
          126  +<li><a href="#4"><b class="cmd">::DiffUtil::compareStreams</b> <span class="opt">?<i class="arg">options</i>?</span> <i class="arg">ch1</i> <i class="arg">ch2</i></a></li>
   125    127   </ul>
   126    128   </div>
   127    129   </div>
   128         -<div id="section1" class="section"><h2><a name="section1">Description</a></h2>
          130  +<div id="section1" class="doctools_section"><h2><a name="section1">Description</a></h2>
   129    131   <p>This package provides utilites for comparisons of strings, lists
   130    132   and files.
   131    133   The base comparison is a Longest Common Substring algorithm based
   132    134   on J. W. Hunt and M. D. McIlroy, &quot;An algorithm for differential
   133    135   file comparison,&quot; Comp. Sci. Tech. Rep. #41, Bell Telephone
   134    136   Laboratories (1976). Available on the Web at the second
   135    137   author's personal site: http://www.cs.dartmouth.edu/~doug/</p>
   136    138   </div>
   137         -<div id="section2" class="section"><h2><a name="section2">COMMANDS</a></h2>
   138         -<dl class="definitions">
          139  +<div id="section2" class="doctools_section"><h2><a name="section2">COMMANDS</a></h2>
          140  +<dl class="doctools_definitions">
   139    141   <dt><a name="1"><b class="cmd">::DiffUtil::diffFiles</b> <span class="opt">?<i class="arg">options</i>?</span> <i class="arg">file1</i> <i class="arg">file2</i></a></dt>
   140    142   <dd><p>Compare two files line by line.
   141    143   The return value depends on the <i class="arg">-result</i> option, see below.</p>
   142         -<dl class="options">
          144  +<dl class="doctools_options">
   143    145   <dt><b class="option">-nocase</b></dt>
   144    146   <dd><p>Ignore case.</p></dd>
   145    147   <dt><b class="option">-i</b></dt>
   146    148   <dd><p>Ignore case.</p></dd>
   147    149   <dt><b class="option">-b</b></dt>
   148    150   <dd><p>Ignore space changes. Any sequence of whitespace is treated as a single
   149    151   space, except at beginning of line where it is completely ignored.</p></dd>
................................................................................
   176    178   on each line.</p></dd>
   177    179   <dt><b class="option">-regsubleft</b> <i class="arg">list</i></dt>
   178    180   <dd><p>Like <i class="arg">-regsub</i> but only applied to the first file.</p></dd>
   179    181   <dt><b class="option">-regsubright</b> <i class="arg">list</i></dt>
   180    182   <dd><p>Like <i class="arg">-regsub</i> but only applied to the second file.</p></dd>
   181    183   <dt><b class="option">-result</b> <i class="arg">style</i></dt>
   182    184   <dd><p>Select result style. The default is <i class="arg">diff</i>.</p>
   183         -<dl class="definitions">
          185  +<dl class="doctools_definitions">
   184    186   <dt><b class="const">diff</b></dt>
   185    187   <dd><p>Returns a list of differences, each in a four element list.
   186    188   {LineNumber1 NumberOfLines1 LineNumber2 NumberOfLines2}
   187    189   The first line in a file is number 1.</p></dd>
   188    190   <dt><b class="const">match</b></dt>
   189    191   <dd><p>The return value is a list of two lists of equal length. The first
   190    192   sublist is of line numbers in <i class="arg">file1</i>, and the second sublist is
................................................................................
   197    199   <dd><p>Apply translation when reading files. This works as for <b class="cmd">fconfigure</b>.</p></dd>
   198    200   <dt><b class="option">-gz</b></dt>
   199    201   <dd><p>Apply gunzip decompression when reading files. Requires zlib.</p></dd>
   200    202   </dl></dd>
   201    203   <dt><a name="2"><b class="cmd">::DiffUtil::diffLists</b> <span class="opt">?<i class="arg">options</i>?</span> <i class="arg">list1</i> <i class="arg">list2</i></a></dt>
   202    204   <dd><p>Compare two lists element by element.
   203    205   The return value depends on the <i class="arg">-result</i> option, see below.</p>
   204         -<dl class="options">
          206  +<dl class="doctools_options">
   205    207   <dt><b class="option">-nocase</b></dt>
   206    208   <dd><p>Ignore case.</p></dd>
   207    209   <dt><b class="option">-i</b></dt>
   208    210   <dd><p>Ignore case.</p></dd>
   209    211   <dt><b class="option">-b</b></dt>
   210    212   <dd><p>Ignore space changes.</p></dd>
   211    213   <dt><b class="option">-w</b></dt>
................................................................................
   217    219   all-space elements are considered empty.
   218    220   Empty elements that obviously matches are noted as equal in a post processing
   219    221   step, but empty elements within change blocks will be reported as changes.</p></dd>
   220    222   <dt><b class="option">-nodigit</b></dt>
   221    223   <dd><p>Consider any sequence of digits equal.</p></dd>
   222    224   <dt><b class="option">-result</b> <i class="arg">style</i></dt>
   223    225   <dd><p>Select result style. The default is <i class="arg">diff</i>.</p>
   224         -<dl class="definitions">
          226  +<dl class="doctools_definitions">
   225    227   <dt><b class="const">diff</b></dt>
   226    228   <dd><p>Returns a list of differences, each in a four element list.
   227    229   {ElementIndex1 NumberOfElements1 ElementIndex2 NumberOfElements2}</p></dd>
   228    230   <dt><b class="const">match</b></dt>
   229    231   <dd><p>The return value is a list of two lists of equal length. The first
   230    232   sublist is of indices in <i class="arg">list1</i>, and the second sublist is
   231    233   of indices in <i class="arg">list2</i>.  Each corresponding pair of indices
   232    234   corresponds to equal elements in the sequences.</p></dd>
   233    235   </dl></dd>
   234    236   </dl></dd>
          237  +<dt><a name="3"><b class="cmd">::DiffUtil::compareFiles</b> <span class="opt">?<i class="arg">options</i>?</span> <i class="arg">file1</i> <i class="arg">file2</i></a></dt>
          238  +<dd><p>Compare two files.
          239  +The return value is a boolean which is true when equal.</p>
          240  +<dl class="doctools_options">
          241  +<dt><b class="option">-nocase</b></dt>
          242  +<dd><p>Ignore case.</p></dd>
          243  +<dt><b class="option">-ignorekey</b></dt>
          244  +<dd><p>Ignore keyword substitutions. This is limited to the first 60k of the file.</p></dd>
          245  +<dt><b class="option">-encoding</b> <i class="arg">enc</i></dt>
          246  +<dd><p>Read files with this encoding. (As in fconfigure -encoding.)</p></dd>
          247  +<dt><b class="option">-translation</b> <i class="arg">trans</i></dt>
          248  +<dd><p>Read files with this translation. (As in fconfigure -translation.)</p></dd>
          249  +</dl></dd>
          250  +<dt><a name="4"><b class="cmd">::DiffUtil::compareStreams</b> <span class="opt">?<i class="arg">options</i>?</span> <i class="arg">ch1</i> <i class="arg">ch2</i></a></dt>
          251  +<dd><p>Compare two channel streams.
          252  +The return value is a boolean which is true when equal.</p>
          253  +<dl class="doctools_options">
          254  +<dt><b class="option">-nocase</b></dt>
          255  +<dd><p>Ignore case.</p></dd>
          256  +<dt><b class="option">-ignorekey</b></dt>
          257  +<dd><p>Ignore keyword substitutions. This is limited to the first 60k read.</p></dd>
          258  +<dt><b class="option">-binary</b></dt>
          259  +<dd><p>Treat stream as binary data. Normally this means it is configured
          260  +with -translation binary.</p></dd>
          261  +</dl></dd>
   235    262   </dl>
   236    263   </div>
   237         -<div id="section3" class="section"><h2><a name="section3">EXAMPLES</a></h2>
   238         -<pre class="example">
          264  +<div id="section3" class="doctools_section"><h2><a name="section3">EXAMPLES</a></h2>
          265  +<pre class="doctools_example">
   239    266   % DiffUtil::diffFiles $file1 $file2
   240    267   {{3 2 3 4}}
   241    268   </pre>
   242    269   </div>
   243         -<div id="keywords" class="section"><h2><a name="keywords">Keywords</a></h2>
          270  +<div id="keywords" class="doctools_section"><h2><a name="keywords">Keywords</a></h2>
   244    271   <p>diff, lcs, longest common substring</p>
   245    272   </div>
   246         -<div id="copyright" class="section"><h2><a name="copyright">Copyright</a></h2>
          273  +<div id="copyright" class="doctools_section"><h2><a name="copyright">Copyright</a></h2>
   247    274   <p>Copyright &copy; 2010, Peter Spjuth</p>
   248    275   </div>
   249    276   </div></body></html>

Changes to undroid/DiffUtilTcl/doc/diffutil.man.

     1         -[manpage_begin DiffUtil n 0.4.0]
            1  +[manpage_begin DiffUtil n 0.4.1]
     2      2   [copyright {2010, Peter Spjuth}]
     3      3   [moddesc   {Comparision Utilities}]
     4      4   [titledesc {Compare Stuff}]
     5      5   [require Tcl 8.6]
     6         -[require DiffUtil [opt 0.4.0]]
            6  +[require DiffUtil [opt 0.4.1]]
     7      7   [description]
     8      8   [para]
     9      9   
    10     10   This package provides utilites for comparisons of strings, lists
    11     11   and files.
    12     12   The base comparison is a Longest Common Substring algorithm based
    13     13   on J. W. Hunt and M. D. McIlroy, "An algorithm for differential
................................................................................
    21     21   
    22     22   [call [cmd "::DiffUtil::diffFiles"] \
    23     23           [opt [arg options]] [arg file1] [arg file2]]
    24     24   
    25     25   Compare two files line by line.
    26     26   The return value depends on the [arg -result] option, see below.
    27     27   
    28         -[list_begin opt]
           28  +[list_begin options]
    29     29   
    30     30   [opt_def -nocase]
    31     31   Ignore case.
    32     32   
    33     33   [opt_def -i]
    34     34   Ignore case.
    35     35   
................................................................................
   102    102   
   103    103   [call [cmd "::DiffUtil::diffLists"] \
   104    104           [opt [arg options]] [arg list1] [arg list2]]
   105    105   
   106    106   Compare two lists element by element.
   107    107   The return value depends on the [arg -result] option, see below.
   108    108   
   109         -[list_begin opt]
          109  +[list_begin options]
   110    110   
   111    111   [opt_def -nocase]
   112    112   Ignore case.
   113    113   
   114    114   [opt_def -i]
   115    115   Ignore case.
   116    116   
................................................................................
   140    140   [def [const match]]
   141    141   The return value is a list of two lists of equal length. The first
   142    142   sublist is of indices in [arg list1], and the second sublist is
   143    143   of indices in [arg list2].  Each corresponding pair of indices
   144    144   corresponds to equal elements in the sequences.
   145    145   [list_end]
   146    146   
          147  +[list_end]
          148  +
          149  +[call [cmd "::DiffUtil::compareFiles"] \
          150  +        [opt [arg options]] [arg file1] [arg file2]]
          151  +
          152  +Compare two files.
          153  +The return value is a boolean which is true when equal.
          154  +
          155  +[list_begin options]
          156  +
          157  +[opt_def -nocase]
          158  +Ignore case.
          159  +
          160  +[opt_def -ignorekey]
          161  +Ignore keyword substitutions. This is limited to the first 60k of the file.
          162  +
          163  +[opt_def -encoding [arg enc]]
          164  +Read files with this encoding. (As in fconfigure -encoding.)
          165  +
          166  +[opt_def -translation [arg trans]]
          167  +Read files with this translation. (As in fconfigure -translation.)
          168  +
          169  +[list_end]
          170  +
          171  +[call [cmd "::DiffUtil::compareStreams"] \
          172  +        [opt [arg options]] [arg ch1] [arg ch2]]
          173  +
          174  +Compare two channel streams.
          175  +The return value is a boolean which is true when equal.
          176  +
          177  +[list_begin options]
          178  +
          179  +[opt_def -nocase]
          180  +Ignore case.
          181  +
          182  +[opt_def -ignorekey]
          183  +Ignore keyword substitutions. This is limited to the first 60k read.
          184  +
          185  +[opt_def -binary]
          186  +Treat stream as binary data. Normally this means it is configured
          187  +with -translation binary.
          188  +
   147    189   [list_end]
   148    190   
   149    191   [list_end]
   150    192   
   151    193   [section EXAMPLES]
   152    194   
   153    195   [para]

Changes to undroid/DiffUtilTcl/doc/diffutil.n.

     1      1   '\"
     2      2   '\" Generated from file 'diffutil\&.man' by tcllib/doctools with format 'nroff'
     3      3   '\" Copyright (c) 2010, Peter Spjuth
     4      4   '\"
     5         -.TH "DiffUtil" n 0\&.4\&.0 diffutil "Comparision Utilities"
            5  +.TH "DiffUtil" n 0\&.4\&.1 diffutil "Comparision Utilities"
     6      6   .\" The -*- nroff -*- definitions below are for supplemental macros used
     7      7   .\" in Tcl/Tk manual entries.
     8      8   .\"
     9      9   .\" .AP type name in/out ?indent?
    10     10   .\"	Start paragraph describing an argument to a library procedure.
    11     11   .\"	type is type of argument (int, etc.), in/out is either "in", "out",
    12     12   .\"	or "in/out" to describe whether procedure reads or modifies arg,
................................................................................
   272    272   ..
   273    273   .BS
   274    274   .SH NAME
   275    275   DiffUtil \- Compare Stuff
   276    276   .SH SYNOPSIS
   277    277   package require \fBTcl  8\&.6\fR
   278    278   .sp
   279         -package require \fBDiffUtil  ?0\&.4\&.0?\fR
          279  +package require \fBDiffUtil  ?0\&.4\&.1?\fR
   280    280   .sp
   281    281   \fB::DiffUtil::diffFiles\fR ?\fIoptions\fR? \fIfile1\fR \fIfile2\fR
   282    282   .sp
   283    283   \fB::DiffUtil::diffLists\fR ?\fIoptions\fR? \fIlist1\fR \fIlist2\fR
          284  +.sp
          285  +\fB::DiffUtil::compareFiles\fR ?\fIoptions\fR? \fIfile1\fR \fIfile2\fR
          286  +.sp
          287  +\fB::DiffUtil::compareStreams\fR ?\fIoptions\fR? \fIch1\fR \fIch2\fR
   284    288   .sp
   285    289   .BE
   286    290   .SH DESCRIPTION
   287    291   .PP
   288    292   This package provides utilites for comparisons of strings, lists
   289    293   and files\&.
   290    294   The base comparison is a Longest Common Substring algorithm based
................................................................................
   414    418   \fBmatch\fR
   415    419   The return value is a list of two lists of equal length\&. The first
   416    420   sublist is of indices in \fIlist1\fR, and the second sublist is
   417    421   of indices in \fIlist2\fR\&.  Each corresponding pair of indices
   418    422   corresponds to equal elements in the sequences\&.
   419    423   .RE
   420    424   .RE
          425  +.TP
          426  +\fB::DiffUtil::compareFiles\fR ?\fIoptions\fR? \fIfile1\fR \fIfile2\fR
          427  +Compare two files\&.
          428  +The return value is a boolean which is true when equal\&.
          429  +.RS
          430  +.TP
          431  +\fB-nocase\fR
          432  +Ignore case\&.
          433  +.TP
          434  +\fB-ignorekey\fR
          435  +Ignore keyword substitutions\&. This is limited to the first 60k of the file\&.
          436  +.TP
          437  +\fB-encoding\fR \fIenc\fR
          438  +Read files with this encoding\&. (As in fconfigure -encoding\&.)
          439  +.TP
          440  +\fB-translation\fR \fItrans\fR
          441  +Read files with this translation\&. (As in fconfigure -translation\&.)
          442  +.RE
          443  +.TP
          444  +\fB::DiffUtil::compareStreams\fR ?\fIoptions\fR? \fIch1\fR \fIch2\fR
          445  +Compare two channel streams\&.
          446  +The return value is a boolean which is true when equal\&.
          447  +.RS
          448  +.TP
          449  +\fB-nocase\fR
          450  +Ignore case\&.
          451  +.TP
          452  +\fB-ignorekey\fR
          453  +Ignore keyword substitutions\&. This is limited to the first 60k read\&.
          454  +.TP
          455  +\fB-binary\fR
          456  +Treat stream as binary data\&. Normally this means it is configured
          457  +with -translation binary\&.
          458  +.RE
   421    459   .PP
   422    460   .SH EXAMPLES
   423    461   .PP
   424    462   .CS
   425    463   
   426    464   
   427    465   % DiffUtil::diffFiles $file1 $file2

Changes to undroid/DiffUtilTcl/generic/comparefiles.c.

     9      9   #include <tcl.h>
    10     10   #include <stdio.h>
    11     11   #include <string.h>
    12     12   #include <stdlib.h>
    13     13   #include <ctype.h>
    14     14   #include <sys/stat.h>
    15     15   #include "diffutil.h"
           16  +
           17  +/* Visual C++ does not define S_ISDIR */
           18  +#ifndef S_ISDIR
           19  +#define S_ISDIR(mode_) (((mode_) & _S_IFMT) == _S_IFDIR)
           20  +#endif
           21  +
           22  +const int BlockRead_C = 65536;
           23  +
           24  +typedef struct {
           25  +    int ignoreKey;
           26  +    int noCase;
           27  +    int binary;
           28  +} CmpOptions_T;
           29  +
           30  +/* Helper to get a filled in CmpOptions_T */
           31  +#define InitCmpOptions_T(opts) {opts.ignoreKey = 0; opts.noCase = 0; opts.binary = 0;}
           32  +
           33  +/* This is called when a dollar is encountered during ignore-keyword.
           34  +   If return is equal res1/2 says how far we covered and considered equal.
           35  +   This do not bother with encoding since the chars we are interested in
           36  +   are the same in ascii/binary/utf8. */
           37  +static int
           38  +ScanKey(
           39  +    const char *s1,
           40  +    const char *s2,
           41  +    const char *e1,
           42  +    const char *e2,
           43  +    const char **res1,
           44  +    const char **res2)
           45  +{
           46  +    *res1 = s1;
           47  +    *res2 = s2;
           48  +    /* Scan word chars until : or $ ends the keyword.
           49  +       They must be equal up to that point. */
           50  +    while (s1 < e1 && s2 < e2) {
           51  +	if ((*s1 == ':' || *s1 == '$') && (*s2 == ':' || *s2 == '$')) {
           52  +	    /* The keyword part has ended on both sides */
           53  +
           54  +	    /* To be a bit conservative and not confuse keywords with e.g.
           55  +	       Tcl namespace variables we only acknowledge these forms:
           56  +	       keyword$
           57  +	       keyword:$
           58  +	       keyword: .*$
           59  +	       keyword:: .*$
           60  +	    */
           61  +	    if (*s1 == ':') {
           62  +		s1++;
           63  +		if (s1 + 1 >= e1) {
           64  +		    return 1;
           65  +		}
           66  +		/* May be a double colon */
           67  +		if (*s1 == ':') {
           68  +		    s1++;
           69  +		}
           70  +		/* Colon must be followed by space or $ */
           71  +		if (*s1 != ' ' && *s1 != '$') {
           72  +		    return 1;
           73  +		}
           74  +	    }
           75  +	    if (*s2 == ':') {
           76  +		s2++;
           77  +		if (s2 + 1 >= e2) {
           78  +		    return 1;
           79  +		}
           80  +		if (*s2 == ':') {
           81  +		    s2++;
           82  +		}
           83  +		if (*s2 != ' ' && *s2 != '$') {
           84  +		    return 1;
           85  +		}
           86  +	    }
           87  +	    break;
           88  +	}
           89  +	if (*s1 != *s2) {
           90  +	    /* They are not equal keywords */
           91  +	    return 0;
           92  +	}
           93  +	/* Only standard ascii word chars count */
           94  +	if ((*s1 >= 'a' && *s1 <= 'z') || (*s1 >= 'A' && *s1 <= 'Z')) {
           95  +	    s1++;
           96  +	    s2++;
           97  +	} else {
           98  +	    /* This did not count as a keyword but is sofar equal. */
           99  +	    *res1 = s1;
          100  +	    *res2 = s2;
          101  +	    return 1;
          102  +	}
          103  +    }
          104  +    /* Skip all until $ */
          105  +    while (s1 < e1) {
          106  +	if (*s1 == '$') {
          107  +	    break;
          108  +	}
          109  +	s1++;
          110  +    }
          111  +    while (s2 < e2) {
          112  +	if (*s2 == '$') {
          113  +	    break;
          114  +	}
          115  +	s2++;
          116  +    }
          117  +    /* At this point s1/2 should point to the dollar ending the keyword. */
          118  +    if (s1 == e1 || s2 == e2) {
          119  +	/* We reached the end of string without finishing the keyword.
          120  +	   If a potential keyword is at the end we don't care. */
          121  +	return 1;
          122  +    }
          123  +    /* Strings are equal up to this point. Skip the last dollar as well. */
          124  +    *res1 = s1 + 1;
          125  +    *res2 = s2 + 1;
          126  +    return 1;
          127  +}
          128  +
          129  +/* Compare two strings, ignoring keywords.
          130  +   If return is true, they are equal up to the point of res1/2. */
          131  +static int
          132  +CompareNoKey(
          133  +    const char *s1,		/* UTF string to compare to s2. */
          134  +    const char *s2,		/* UTF string s2 is compared to. */
          135  +    unsigned long len1,		/* Number of bytes to compare. */
          136  +    unsigned long len2,
          137  +    CmpOptions_T *cmpOptions,
          138  +    const char **res1,
          139  +    const char **res2)
          140  +{
          141  +    Tcl_UniChar ch1 = 0, ch2 = 0;
          142  +    const char *end1 = s1 + len1;
          143  +    const char *end2 = s2 + len2;
          144  +    const char *scan1, *scan2;
          145  +
          146  +    while (s1 < end1 && s2 < end2) {
          147  +	if (cmpOptions->binary) {
          148  +	    ch1 = *(s1++);
          149  +	    ch2 = *(s2++);
          150  +	} else {
          151  +	    s1 += Tcl_UtfToUniChar(s1, &ch1);
          152  +	    s2 += Tcl_UtfToUniChar(s2, &ch2);
          153  +	}
          154  +	if (ch1 != ch2) {
          155  +	    if (cmpOptions->noCase) {
          156  +		ch1 = Tcl_UniCharToLower(ch1);
          157  +		ch2 = Tcl_UniCharToLower(ch2);
          158  +		if (ch1 != ch2) {
          159  +		    return 0;
          160  +		}
          161  +	    } else {
          162  +		return 0;
          163  +	    }
          164  +	}
          165  +	if (ch1 == '$') {
          166  +	    if (!ScanKey(s1, s2, end1, end2, &scan1, &scan2)) {
          167  +		/* If ScanKey said not equal, we trust it unless we use
          168  +		   less strict rules */
          169  +		if (!cmpOptions->noCase) {
          170  +		    return 0;
          171  +		}
          172  +	    }
          173  +	    s1 = scan1;
          174  +	    s2 = scan2;
          175  +	}
          176  +    }
          177  +    *res1 = s1;
          178  +    *res2 = s2;
          179  +    return 1;
          180  +}
          181  +
          182  +static int
          183  +CompareStreams(
          184  +    Tcl_Channel ch1,
          185  +    Tcl_Channel ch2,
          186  +    CmpOptions_T *cmpOptions)
          187  +{
          188  +    int equal;
          189  +    Tcl_Obj *line1Ptr, *line2Ptr;
          190  +    int charactersRead1, charactersRead2;
          191  +    int length1, length2;
          192  +    int firstblock;
          193  +    const char *string1, *string2;
          194  +
          195  +    /* Initialize an object to use as line buffer. */
          196  +    line1Ptr = Tcl_NewObj();
          197  +    line2Ptr = Tcl_NewObj();
          198  +    Tcl_IncrRefCount(line1Ptr);
          199  +    Tcl_IncrRefCount(line2Ptr);
          200  +    if (cmpOptions->binary) {
          201  +	Tcl_SetByteArrayLength(line1Ptr, 70000);
          202  +	Tcl_SetByteArrayLength(line2Ptr, 70000);
          203  +    } else {
          204  +	Tcl_SetObjLength(line1Ptr, 70000);
          205  +	Tcl_SetObjLength(line2Ptr, 70000);
          206  +    }
          207  +
          208  +    equal = 1;
          209  +    firstblock = 1;
          210  +    while (equal) {
          211  +	charactersRead1 = Tcl_ReadChars(ch1, line1Ptr, BlockRead_C, 0);
          212  +	charactersRead2 = Tcl_ReadChars(ch2, line2Ptr, BlockRead_C, 0);
          213  +	if (charactersRead1 <= 0 && charactersRead2 <= 0) {
          214  +	    /* Nothing more to check */
          215  +	    break;
          216  +	}
          217  +	if (charactersRead1 <= 0 || charactersRead2 <= 0) {
          218  +	    /* One of the files is ended */
          219  +	    equal = 0;
          220  +	    break;
          221  +	}
          222  +	if (charactersRead1 != charactersRead2  && !cmpOptions->ignoreKey) {
          223  +	    /* Different size */
          224  +	    equal = 0;
          225  +	    break;
          226  +	}
          227  +	if (cmpOptions->binary) {
          228  +	    string1 = (char *) Tcl_GetByteArrayFromObj(line1Ptr, &length1);
          229  +	    string2 = (char *) Tcl_GetByteArrayFromObj(line2Ptr, &length2);
          230  +	} else {
          231  +	    string1 = Tcl_GetStringFromObj(line1Ptr, &length1);
          232  +	    string2 = Tcl_GetStringFromObj(line2Ptr, &length2);
          233  +	}
          234  +	/* Limit ignoreKey to first block to simplify.
          235  +	   No need to handle keywords crossing block boundary and a bit
          236  +	   better performance on large files. */
          237  +	if (firstblock && cmpOptions->ignoreKey) {
          238  +	    const char *res1, *res2;
          239  +	    unsigned long rem1, rem2;
          240  +	    int eq = CompareNoKey(string1, string2, length1, length2,
          241  +				  cmpOptions, &res1, &res2);
          242  +	    if (!eq) {
          243  +		equal = 0;
          244  +		break;
          245  +	    }
          246  +	    firstblock = 0;
          247  +	    /* Did we consume everything? */
          248  +	    if (res1 >= string1 + length1 && res2 >= string2 + length2) {
          249  +		continue;
          250  +	    }
          251  +	    /* Compensate for any change in length. */
          252  +	    rem1 = length1 - (res1 - string1);
          253  +	    rem2 = length2 - (res2 - string2);
          254  +	    /* Only one side should have anything left. */
          255  +	    if (rem1 > 0 && rem2 > 0) { Tcl_Panic("PANIC"); }
          256  +	    if (rem1 > 0) {
          257  +		unsigned long chars1;
          258  +		/* Adjust side 1 */
          259  +		string1 = res1;
          260  +		length1 = rem1;
          261  +		chars1 = Tcl_NumUtfChars(string1, length1);
          262  +		/* Read extra characters from side 2 */
          263  +		charactersRead2 = Tcl_ReadChars(ch2, line2Ptr, chars1, 0);
          264  +		if (charactersRead2 <= 0) {
          265  +		    equal = 0;
          266  +		    break;
          267  +		}
          268  +		if (cmpOptions->binary) {
          269  +		    string2 = (char *) Tcl_GetByteArrayFromObj(line2Ptr, &length2);
          270  +		} else {
          271  +		    string2 = Tcl_GetStringFromObj(line2Ptr, &length2);
          272  +		}
          273  +	    } else { /* rem2 > 0 */
          274  +		unsigned long chars2;
          275  +		/* Adjust side 2 */
          276  +		string2 = res2;
          277  +		length2 = rem2;
          278  +		chars2 = Tcl_NumUtfChars(string2, length2);
          279  +		/* Read extra characters from side 1 */
          280  +		charactersRead1 = Tcl_ReadChars(ch1, line1Ptr, chars2, 0);
          281  +		if (charactersRead1 <= 0) {
          282  +		    equal = 0;
          283  +		    break;
          284  +		}
          285  +		if (cmpOptions->binary) {
          286  +		    string1 = (char *) Tcl_GetByteArrayFromObj(line1Ptr, &length1);
          287  +		} else {
          288  +		    string1 = Tcl_GetStringFromObj(line1Ptr, &length1);
          289  +		}
          290  +	    }
          291  +	}
          292  +	if (length1 != length2) {
          293  +	    equal = 0;
          294  +	    break;
          295  +	}
          296  +	if (cmpOptions->binary) {
          297  +	    if (strncmp(string1, string2, length1) != 0) {
          298  +		equal = 0;
          299  +		break;
          300  +	    }
          301  +	} else if (cmpOptions->noCase) {
          302  +	    if (Tcl_UtfNcasecmp(string1, string2, length1) != 0) {
          303  +		equal = 0;
          304  +		break;
          305  +	    }
          306  +	} else {
          307  +	    if (Tcl_UtfNcmp(string1, string2, length1) != 0) {
          308  +		equal = 0;
          309  +		break;
          310  +	    }
          311  +	}
          312  +    }
          313  +
          314  +    Tcl_DecrRefCount(line1Ptr);
          315  +    Tcl_DecrRefCount(line2Ptr);
          316  +    return equal;
          317  +}
    16    318   
    17    319   int
    18    320   CompareFilesObjCmd(
    19    321       ClientData dummy,    	/* Not used. */
    20    322       Tcl_Interp *interp,		/* Current interpreter. */
    21    323       int objc,			/* Number of arguments. */
    22    324       Tcl_Obj *CONST objv[])	/* Argument objects. */
    23    325   {
    24    326       int index, t, result = TCL_OK;
    25    327       Tcl_Obj *file1Ptr, *file2Ptr;
    26         -    int ignoreKey = 0, binary = 0, equal = 0;
          328  +    int equal = 0;
          329  +    CmpOptions_T cmpOptions;
    27    330       Tcl_Obj *encodingPtr = NULL;
    28    331       Tcl_Obj *translationPtr = NULL;
    29    332       Tcl_StatBuf *statBuf;
    30    333       Tcl_Channel ch1 = NULL, ch2 = NULL;
    31         -    Tcl_Obj *line1Ptr, *line2Ptr;
    32    334       Tcl_WideUInt size1, size2;
    33    335       unsigned mode1, mode2;
    34         -    int charactersRead1, charactersRead2;
    35         -    int length1, length2;
    36         -    char *string1, *string2;
    37    336   
    38    337       static CONST char *options[] = {
    39    338   	"-nocase", "-ignorekey", "-encoding",
    40    339           "-translation", (char *) NULL
    41    340       };
    42    341       enum options {
    43    342   	OPT_NOCASE, OPT_IGNOREKEY, OPT_ENCODING,
................................................................................
    44    343           OPT_TRANSLATION
    45    344       };
    46    345   
    47    346       if (objc < 3) {
    48    347           Tcl_WrongNumArgs(interp, 1, objv, "?opts? file1 file2");
    49    348   	return TCL_ERROR;
    50    349       }
          350  +    InitCmpOptions_T(cmpOptions);
    51    351   
    52    352       for (t = 1; t < objc - 2; t++) {
    53    353   	if (Tcl_GetIndexFromObj(interp, objv[t], options, "option", 0,
    54    354   		&index) != TCL_OK) {
    55    355               result = TCL_ERROR;
    56    356               goto cleanup;
    57    357   	}
    58    358   	switch (index) {
    59    359   	  case OPT_NOCASE:
          360  +	      cmpOptions.noCase = 1;
    60    361   	      break;
    61    362   	  case OPT_IGNOREKEY:
    62         -	      ignoreKey = 1;
          363  +	      cmpOptions.ignoreKey = 1;
    63    364   	      break;
    64    365   	  case OPT_ENCODING:
    65    366   	      t++;
    66    367   	      if (t >= objc - 2) {
    67    368   		  Tcl_WrongNumArgs(interp, 1, objv, "?opts? file1 file2");
    68    369   		  result = TCL_ERROR;
    69    370   		  goto cleanup;
................................................................................
    85    386       }
    86    387       file1Ptr = objv[objc-2];
    87    388       file2Ptr = objv[objc-1];
    88    389   
    89    390       if (translationPtr != NULL) {
    90    391   	char *valueName = Tcl_GetString(translationPtr);
    91    392   	if (strcmp(valueName, "binary") == 0) {
    92         -	    binary = 1;
          393  +	    cmpOptions.binary = 1;
    93    394   	}
    94    395       }
    95    396   
    96    397       statBuf = Tcl_AllocStatBuf();
    97    398   
    98    399       /* Stat files first to quickly see if they don't exist */
    99    400       if (Tcl_FSStat(file1Ptr, statBuf) != 0) {
................................................................................
   117    418       ckfree((char *) statBuf);
   118    419   
   119    420       if (S_ISDIR(mode1) || S_ISDIR(mode2)) {
   120    421   	equal = 0;
   121    422   	goto done;
   122    423       }
   123    424       /* On binary comparison, different size means different */
   124         -    if (binary && !ignoreKey && size1 != size2) {
          425  +    if (cmpOptions.binary && !cmpOptions.ignoreKey && size1 != size2) {
   125    426   	equal = 0;
   126    427   	goto done;
   127    428       }
   128         -    
          429  +
   129    430       ch1 = Tcl_FSOpenFileChannel(interp, file1Ptr, "r", 0);
   130    431       if (ch1 == NULL) {
   131    432           result = TCL_ERROR;
   132    433           goto cleanup;
   133    434       }
   134    435       ch2 = Tcl_FSOpenFileChannel(interp, file2Ptr, "r", 0);
   135    436       if (ch2 == NULL) {
................................................................................
   158    459   	}
   159    460   	if (Tcl_SetChannelOption(interp, ch2, "-translation", valueName)
   160    461   		!= TCL_OK) {
   161    462   	    result = TCL_ERROR;
   162    463   	    goto cleanup;
   163    464   	}
   164    465       }
   165         -
   166         -    /* Initialize an object to use as line buffer. */
   167         -    line1Ptr = Tcl_NewObj();
   168         -    line2Ptr = Tcl_NewObj();
   169         -    Tcl_IncrRefCount(line1Ptr);
   170         -    Tcl_IncrRefCount(line2Ptr);
   171         -    if (binary) {
   172         -	Tcl_SetByteArrayLength(line1Ptr, 70000);
   173         -	Tcl_SetByteArrayLength(line2Ptr, 70000);
   174         -    } else {
   175         -	Tcl_SetObjLength(line1Ptr, 70000);
   176         -	Tcl_SetObjLength(line2Ptr, 70000);
   177         -    }
   178         -
   179         -    equal = 1;
   180         -    while (1) {
   181         -	charactersRead1 = Tcl_ReadChars(ch1, line1Ptr, 65536, 0);
   182         -	charactersRead2 = Tcl_ReadChars(ch2, line2Ptr, 65536, 0);
   183         -	if (charactersRead1 <= 0 && charactersRead2 <= 0) {
   184         -	    /* Nothing more to check */
   185         -	    break;
   186         -	}
   187         -	if (charactersRead1 <= 0 || charactersRead2 <= 0) {
   188         -	    /* One of the files is ended */
   189         -	    equal = 0;
   190         -	    break;
   191         -	}
   192         -	if (charactersRead1 != charactersRead2  && !ignoreKey) {
   193         -	    /* Different size */
   194         -	    equal = 0;
   195         -	    break;
   196         -	}
   197         -	if (binary) {
   198         -	    string1 = (char *) Tcl_GetByteArrayFromObj(line1Ptr, &length1);
   199         -	    string2 = (char *) Tcl_GetByteArrayFromObj(line2Ptr, &length2);
   200         -	} else {
   201         -	    string1 = Tcl_GetStringFromObj(line1Ptr, &length1);
   202         -	    string2 = Tcl_GetStringFromObj(line2Ptr, &length2);
   203         -	}
   204         -	if (ignoreKey) {
   205         -
   206         -	} else {
   207         -	    if (length1 != length2) {
   208         -		equal = 0;
   209         -		break;
   210         -	    }
   211         -	    if (binary) {
   212         -		if (strncmp(string1, string2, length1) != 0) {
   213         -		    equal = 0;
   214         -		    break;
   215         -		}
   216         -	    } else {
   217         -		if (Tcl_UtfNcmp(string1, string2, length1) != 0) {
   218         -		    equal = 0;
   219         -		    break;
   220         -		}
   221         -	    }
   222         -	}
   223         -    }
   224         -
   225         -    Tcl_DecrRefCount(line1Ptr);
   226         -    Tcl_DecrRefCount(line2Ptr);
          466  +    equal = CompareStreams(ch1, ch2, &cmpOptions);
   227    467   
   228    468       done:
   229    469       Tcl_SetObjResult(interp, Tcl_NewIntObj(equal));
   230    470   
   231    471       cleanup:
   232    472   
   233    473       if (ch1 != NULL) {
................................................................................
   241    481       }
   242    482       if (translationPtr != NULL) {
   243    483   	Tcl_DecrRefCount(translationPtr);
   244    484       }
   245    485   
   246    486       return result;
   247    487   }
          488  +
          489  +int
          490  +CompareStreamsObjCmd(
          491  +    ClientData dummy,    	/* Not used. */
          492  +    Tcl_Interp *interp,		/* Current interpreter. */
          493  +    int objc,			/* Number of arguments. */
          494  +    Tcl_Obj *CONST objv[])	/* Argument objects. */
          495  +{
          496  +    int index, t, result = TCL_OK;
          497  +    int equal;
          498  +    CmpOptions_T cmpOptions;
          499  +    Tcl_Channel ch1, ch2;
          500  +
          501  +    static CONST char *options[] = {
          502  +	"-nocase", "-ignorekey", "-binary",
          503  +        (char *) NULL
          504  +    };
          505  +    enum options {
          506  +	OPT_NOCASE, OPT_IGNOREKEY, OPT_BINARY
          507  +    };
          508  +
          509  +    if (objc < 3) {
          510  +        Tcl_WrongNumArgs(interp, 1, objv, "?opts? ch1 ch2");
          511  +	return TCL_ERROR;
          512  +    }
          513  +    InitCmpOptions_T(cmpOptions);
          514  +
          515  +    for (t = 1; t < objc - 2; t++) {
          516  +	if (Tcl_GetIndexFromObj(interp, objv[t], options, "option", 0,
          517  +		&index) != TCL_OK) {
          518  +            result = TCL_ERROR;
          519  +            goto cleanup;
          520  +	}
          521  +	switch (index) {
          522  +	  case OPT_NOCASE:
          523  +	      cmpOptions.noCase = 1;
          524  +	      break;
          525  +	  case OPT_IGNOREKEY:
          526  +	      cmpOptions.ignoreKey = 1;
          527  +	      break;
          528  +	  case OPT_BINARY:
          529  +	      cmpOptions.binary = 1;
          530  +	      break;
          531  +	}
          532  +    }
          533  +
          534  +    ch1 = Tcl_GetChannel(interp, Tcl_GetString(objv[objc-2]), NULL);
          535  +    if (ch1 == NULL) {
          536  +	result = TCL_ERROR;
          537  +	goto cleanup;
          538  +    }
          539  +    ch2 = Tcl_GetChannel(interp, Tcl_GetString(objv[objc-1]), NULL);
          540  +    if (ch2 == NULL) {
          541  +	result = TCL_ERROR;
          542  +	goto cleanup;
          543  +    }
          544  +
          545  +    equal = CompareStreams(ch1, ch2, &cmpOptions);
          546  +    Tcl_SetObjResult(interp, Tcl_NewIntObj(equal));
          547  +
          548  +    cleanup:
          549  +    return result;
          550  +}

Changes to undroid/DiffUtilTcl/generic/diff.c.

    22     22   #include "diffutil.h"
    23     23   
    24     24   /* A type for the parsing state */
    25     25   typedef enum {
    26     26       IN_NONE, IN_SPACE, IN_NUMBER
    27     27   } In_T;
    28     28   
           29  +/*
           30  + * max already defined by Visual C++, but reuse our def just in case
           31  + * semantics differ.
           32  + */
           33  +#ifdef max
           34  +#undef max /* Unset to prevent preprocessor warnings */
           35  +#endif
    29     36   #define max(a,b) ((a) > (b) ? (a) : (b))
    30     37   
    31     38   /* A type to implement the Candidates in the LCS algorithm */
    32     39   typedef struct Candidate_T {
    33     40       /* Line numbers in files */
    34     41       Line_T line1, line2;
    35     42       /* A score value to select between similar candidates */
................................................................................
   937    944           }
   938    945           return;
   939    946       }
   940    947   
   941    948       /*
   942    949        * In principle this matching should be a rerun of LCS on the block, with
   943    950        * forbidden lines allowed.
   944         -     * If the group is larger than the pivot, we do not want to recurse to LCS
          951  +     * If the group is much larger than the pivot, we do not want to recurse to LCS
   945    952        * since that would just repeat the timing problem we try to avoid.
          953  +     * Small lists are ok (we should not skip this when pivot=1).
   946    954        */
   947         -    if (jList->n < optsPtr->pivot) {
          955  +    if (jList->n < 20 || jList->n < optsPtr->pivot * 2) { /* TBD how much larger is ok? */
   948    956           int anyForbidden;
   949    957           Line_T *newJ;
   950    958           DiffOptions_T opts = *optsPtr;
   951    959           opts.rFrom1 = firstI;
   952    960           opts.rTo1   = lastI;
   953    961           opts.rFrom2 = firstJ;
   954    962           opts.rTo2   = lastJ;
................................................................................
   962    970           return;
   963    971       }
   964    972   
   965    973       /*
   966    974        * Just do a raw sequential matching of forbidden lines.
   967    975        * This produces a reasonable, if non-optimal, result.
   968    976        * FIXA: Better algorithm here?
   969         -     */ 
          977  +     */
   970    978       for (j = 0; j < iList->n && j < jList->n; j++) {
   971    979           Line_T line1 = iList->Elems[j].line;
   972    980           Line_T line2 = jList->Elems[j].line;
   973    981           if (IsLineMatch(&iList->Elems[j], &jList->Elems[j], optsPtr)) {
   974    982               J[line1] = line2;
   975    983           }
   976    984       }
   977    985   }
   978         -        
          986  +
   979    987   /*
   980    988    * We have ignored forbidden lines before which means that there
   981    989    * may be more lines that can be matched.
   982    990    */
   983    991   static void
   984    992   PostProcessForbidden(
   985    993       Tcl_Interp *interp,
................................................................................
  1044   1052           }
  1045   1053           if (P[i].forbidden) {
  1046   1054               /* Make a list of all forbidden lines in this change block. */
  1047   1055               AddToLineList(&iList, i, P[i].hash);
  1048   1056               continue;
  1049   1057           }
  1050   1058       }
  1051         -    
         1059  +
  1052   1060       FreeLineList(&iList);
  1053   1061       FreeLineList(&jList);
  1054   1062       /*
  1055   1063        * This could be left to block matching if that is improved
  1056   1064        * to handle equal lines within change blocks.
  1057   1065        */
  1058   1066   }
................................................................................
  1076   1084   
  1077   1085   
  1078   1086   /*
  1079   1087    * The core part of the LCS algorithm.
  1080   1088    * It is independent of data since it only works on hashes.
  1081   1089    *
  1082   1090    * This is the inner part of it, which do not meddle with forbidden lines.
  1083         - * It respects them, but do not add or clean up any forbidden lines.
  1084         - * 
         1091  + * It normally respects them, but do not add or clean up any forbidden lines.
         1092  + *
  1085   1093    * Returns the J vector as a ckalloc:ed array.
  1086   1094    */
  1087   1095   static Line_T *
  1088   1096   LcsCoreInner(
  1089   1097       Tcl_Interp *interp,
  1090   1098       Line_T m,      /* number of elements in first sequence */
  1091   1099       Line_T n,      /* number of elements in second sequence */
  1092   1100       const P_T *P,  /* The P vector [0,m] corresponds to lines in "file 1" */
  1093   1101       const E_T *E,  /* The E vector [0,n] corresponds to lines in "file 2" */
  1094   1102       const DiffOptions_T *optsPtr,
  1095   1103       int ignoreForbidden,
  1096         -    int *anyForbidden) /* Out parameter, was any forbidden lines skipped? */
         1104  +    int *anyForbidden) /* Out parameter: Was any forbidden lines skipped? */
  1097   1105   {
  1098   1106       Candidate_T **K, *c;
  1099   1107       Line_T i, k, *J;
  1100   1108       /* Keep track of all candidates to free them easily */
  1101   1109       CandidateAlloc_T *candidates = NULL;
  1102         -    
         1110  +
  1103   1111       *anyForbidden = 0;
  1104   1112   
  1105   1113       /*printf("Doing K\n"); */
  1106   1114   
  1107   1115       /* Initialise K candidate vector */
  1108   1116       K = (Candidate_T **) ckalloc(sizeof(Candidate_T *) * ((m < n ? m : n) + 2));
  1109   1117   
................................................................................
  1271   1279       Tcl_Interp *interp,
  1272   1280       Line_T m, Line_T n,
  1273   1281       P_T *P, E_T *E,
  1274   1282       const DiffOptions_T *optsPtr)
  1275   1283   {
  1276   1284       Line_T i, *J;
  1277   1285       int anyForbidden;
  1278         -    
         1286  +
  1279   1287       for (i = 1; i <= m; i++) {
  1280   1288           if (P[i].Eindex != 0) {
  1281   1289               if (optsPtr->noempty && P[i].hash == 0) {
  1282   1290                   /* Uphold the -noempty rule by forbidding those connections */
  1283   1291                   ForbidP(i, P, E);
  1284   1292               }
  1285   1293               if (E[P[i].Eindex].count > optsPtr->pivot) {
................................................................................
  1692   1700    */
  1693   1701   static int
  1694   1702   DiffOptsRegsub(
  1695   1703       Tcl_Interp *interp,           /* Current interpreter. */
  1696   1704       Tcl_Obj *obj1Ptr,             /* Input object. */
  1697   1705       Tcl_Obj *rePtr,               /* Regexp object. */
  1698   1706       Tcl_Obj *sub1Ptr,             /* Substitution. */
  1699         -    Tcl_Obj **resultPtrPtr,       /* Store result, if successful. */ 
  1700         -    const DiffOptions_T *optsPtr) /* Options. */ 
         1707  +    Tcl_Obj **resultPtrPtr,       /* Store result, if successful. */
         1708  +    const DiffOptions_T *optsPtr) /* Options. */
  1701   1709   {
  1702   1710       int idx, result, cflags, all, wlen, wsublen, numMatches, offset;
  1703   1711       int start, end, subStart, subEnd, match;
  1704   1712       Tcl_RegExp regExpr;
  1705   1713       Tcl_RegExpInfo info;
  1706   1714       Tcl_Obj *resultPtr, *objPtr, *subPtr;
  1707   1715       Tcl_UniChar ch, *wsrc, *wfirstChar, *wstring, *wsubspec, *wend;

Changes to undroid/DiffUtilTcl/generic/diffstrings.c.

   116    116       Tcl_UniChar c;
   117    117       Tcl_Obj *resPtr;
   118    118       int igSpace = (optsPtr->ignore & (IGNORE_SPACE_CHANGE | IGNORE_ALL_SPACE));
   119    119       int word = optsPtr->wordparse;
   120    120   
   121    121       resPtr = Tcl_NewListObj(0, NULL);
   122    122       Tcl_IncrRefCount(resPtr);
   123         -    
          123  +
   124    124       string = Tcl_GetStringFromObj(strPtr, &length);
   125    125       str = string;
   126    126       startWord = str;
   127    127       while (*str != 0) {
   128    128           endWord = str;
   129    129           chsize = Tcl_UtfToUniChar(str, &c);
   130    130           isSpace = Tcl_UniCharIsSpace(c);
................................................................................
   405    405               Tcl_ListObjAppendElement(interp, *resPtr, str1Ptr);
   406    406               Tcl_ListObjAppendElement(interp, *resPtr, str2Ptr);
   407    407               Tcl_ListObjAppendElement(interp, *resPtr, emptyPtr);
   408    408               Tcl_ListObjAppendElement(interp, *resPtr, emptyPtr);
   409    409           }
   410    410           return;
   411    411       }
   412         -    
          412  +
   413    413       if ((optsPtr->ignore & (IGNORE_SPACE_CHANGE | IGNORE_ALL_SPACE)) ||
   414    414           optsPtr->wordparse) {
   415    415           /* Do it chunk-wise through list diff */
   416    416           CompareStringsL(interp, str1Ptr, str2Ptr, optsPtr, resPtr);
   417    417           return;
   418    418       }
   419    419   

Changes to undroid/DiffUtilTcl/generic/diffutil.c.

    28     28       int match;
    29     29       CompareFun *cmp;
    30     30       Tcl_UniChar first1, c2;
    31     31   
    32     32       /*
    33     33        * We are searching string2 for the sequence string1.
    34     34        */
    35         -    
           35  +
    36     36       match = -1;
    37     37       if (length1 < 0)
    38     38   	length1 = Tcl_UniCharLen(ustring1);
    39     39       if (length2 < 0)
    40     40   	length2 = Tcl_UniCharLen(ustring2);
    41     41   
    42     42       if (nocase) {
................................................................................
   200    200       Tcl_DecrRefCount(apa2);
   201    201   
   202    202       /* Handle middle (common) part*/
   203    203       Tcl_ListObjAppendElement(interp, res,
   204    204   	    Tcl_NewUnicodeObj(str1 + found1, foundlen));
   205    205       Tcl_ListObjAppendElement(interp, res,
   206    206   	    Tcl_NewUnicodeObj(str2 + found2, foundlen));
   207         -    
          207  +
   208    208       /* Handle right part, recursively*/
   209    209       apa1 = Tcl_NewUnicodeObj(str1 + found1 + foundlen, -1);
   210    210       apa2 = Tcl_NewUnicodeObj(str2 + found2 + foundlen, -1);
   211    211       Tcl_IncrRefCount(apa1);
   212    212       Tcl_IncrRefCount(apa2);
   213    213       CompareMidString(interp, apa1, apa2, res, wordparse, nocase);
   214    214       Tcl_DecrRefCount(apa1);
................................................................................
   232    232       int wordflag;
   233    233       Tcl_Obj *res, *mid1, *mid2;
   234    234       static CONST char *options[] = {
   235    235   	"-nocase", "-i", "-b", "-w", "-words", (char *) NULL
   236    236       };
   237    237       enum options {
   238    238   	OPT_NOCASE, OPT_I, OPT_B, OPT_W, OPT_WORDS
   239         -    };	  
          239  +    };
   240    240   
   241    241       if (objc < 3) {
   242    242           Tcl_WrongNumArgs(interp, 1, objv, "?opts? line1 line2");
   243    243   	return TCL_ERROR;
   244    244       }
   245         -    
          245  +
   246    246       for (t = 1; t < objc - 2; t++) {
   247    247   	if (Tcl_GetIndexFromObj(interp, objv[t], options, "option", 0,
   248    248   		&index) != TCL_OK) {
   249    249   	    return TCL_ERROR;
   250    250   	}
   251    251   	switch (index) {
   252    252             case OPT_NOCASE :
................................................................................
   263    263   	    wordparse = 1;
   264    264   	    break;
   265    265   	}
   266    266       }
   267    267   
   268    268       line1 = Tcl_GetUnicodeFromObj(objv[objc-2], &len1);
   269    269       line2 = Tcl_GetUnicodeFromObj(objv[objc-1], &len2);
   270         -    
          270  +
   271    271       s1 = line1;
   272    272       s2 = line2;
   273    273       e1 = line1 + len1;
   274    274       e2 = line2 + len2;
   275    275   
   276    276       /* Skip whitespace in both ends*/
   277    277       if (ignore > 0) {
   278    278   	while (s1 < e1 && Tcl_UniCharIsSpace(*s1)) s1++;
   279    279   	while (s2 < e2 && Tcl_UniCharIsSpace(*s2)) s2++;
   280    280   	while (e1 > s1 && Tcl_UniCharIsSpace(*(e1-1))) e1--;
   281    281   	while (e2 > s2 && Tcl_UniCharIsSpace(*(e2-1))) e2--;
   282    282       }
   283         -    
          283  +
   284    284       /* Skip matching chars in both ends
   285    285        * Forwards */
   286    286       word1 = s1; word2 = s2;
   287    287       wordflag = 0;
   288    288       while (s1 < e1 && s2 < e2) {
   289    289   	if (wordflag) {
   290    290   	    word1 = s1;
................................................................................
   382    382       }
   383    383   #endif
   384    384       if (Tcl_PkgProvide(interp, PACKAGE_NAME, PACKAGE_VERSION) != TCL_OK) {
   385    385   	return TCL_ERROR;
   386    386       }
   387    387   
   388    388       TCOC("DiffUtil::compareFiles", CompareFilesObjCmd);
          389  +    TCOC("DiffUtil::compareStreams", CompareStreamsObjCmd);
   389    390       TCOC("DiffUtil::diffFiles", DiffFilesObjCmd);
   390    391       TCOC("DiffUtil::diffLists", DiffListsObjCmd);
   391    392       TCOC("DiffUtil::diffStrings", DiffStringsObjCmd);
   392    393       TCOC("DiffUtil::diffStrings2", DiffStrings2ObjCmd);
   393    394       Tcl_SetVar(interp, "DiffUtil::version", PACKAGE_VERSION, TCL_GLOBAL_ONLY);
   394    395       Tcl_SetVar(interp, "DiffUtil::implementation", "c", TCL_GLOBAL_ONLY);
   395    396   

Changes to undroid/DiffUtilTcl/generic/diffutil.h.

    43     43       int alignLength;
    44     44       Line_T *align;
    45     45       Line_T staticAlign[STATIC_ALIGN];
    46     46   } DiffOptions_T;
    47     47   
    48     48   /* Helper to get a filled in DiffOptions_T */
    49     49   #define InitDiffOptions_T(opts) {opts.ignore = 0; opts.noempty = 0; opts.pivot = 10; opts.wordparse = 0; opts.rFrom1 = 1; opts.rTo1 = 0; opts.rFrom2 = 1; opts.rTo2 = 0; opts.regsubLeftPtr = NULL; opts.regsubRightPtr = NULL; opts.resultStyle = Result_Diff; opts.firstIndex = 1; opts.alignLength = 0; opts.align = opts.staticAlign;}
    50         - 
           50  +
    51     51   /* Flags in DiffOptions_T's ignore field */
    52     52   
    53     53   #define IGNORE_ALL_SPACE 1
    54     54   #define IGNORE_SPACE_CHANGE 2
    55     55   #define IGNORE_CASE 4
    56     56   #define IGNORE_NUMBERS 8
    57     57   
................................................................................
   140    140   			DiffOptions_T *optsPtr);
   141    141   extern void      SortV(V_T *V, Line_T n, const DiffOptions_T *optsPtr);
   142    142   
   143    143   
   144    144   extern int
   145    145   CompareFilesObjCmd(ClientData dummy,
   146    146                   Tcl_Interp *interp,
          147  +                int objc,
          148  +                Tcl_Obj *CONST objv[]);
          149  +extern int
          150  +CompareStreamsObjCmd(ClientData dummy,
          151  +                Tcl_Interp *interp,
   147    152                   int objc,
   148    153                   Tcl_Obj *CONST objv[]);
   149    154   
   150    155   extern int
   151    156   DiffFilesObjCmd(ClientData dummy,
   152    157                   Tcl_Interp *interp,
   153    158                   int objc,

Changes to undroid/DiffUtilTcl/makevfs.sh.

     1      1   # Script to build a multi-platform vfs
            2  +
            3  +# Do this separately on mac:
            4  +# ./configure
            5  +# make clean
            6  +# make
            7  +# make vfsmac
     2      8   
     3      9   # Cross-compiling needs a cross-compiled tcl for linking
     4     10   ./configure --host=i586-mingw32msvc --target=i586-mingw32msvc --with-tcl=/home/peter/tcl/win/tcl/win
     5     11   make clean
     6     12   make
     7     13   make vfswin
     8     14   
................................................................................
    12     18   make
    13     19   make vfs32
    14     20   
    15     21   ./configure --enable-64bit --with-tcl=/home/peter/tcl/v86/tcl/unix
    16     22   make clean
    17     23   make
    18     24   make vfs64
           25  +
           26  +# End with a sanity check
           27  +ls -l lib.vfs/DiffUtil/*/*.so lib.vfs/DiffUtil/*/*.dylib lib.vfs/DiffUtil/*/*.dll
           28  +file lib.vfs/DiffUtil/*/*.so lib.vfs/DiffUtil/*/*.dylib lib.vfs/DiffUtil/*/*.dll

Changes to undroid/DiffUtilTcl/tcl/diffutil.tcl.

     7      7   #  This package is starting out as a refactoring of diff code from
     8      8   #  Eskil, and will be released as a separate package when mature.
     9      9   #
    10     10   #----------------------------------------------------------------------
    11     11   # $Revision: 1.12 $
    12     12   #----------------------------------------------------------------------
    13     13   
    14         -package provide DiffUtil 0.4.0
           14  +package provide DiffUtil 0.4.1
    15     15   
    16     16   namespace eval DiffUtil {
    17     17       namespace export diffFiles diffStrings
    18     18       variable version [package provide DiffUtil]
    19     19       variable implementation "tcl"
    20     20   }
    21     21   

Changes to undroid/DiffUtilTcl/tests/comparefiles.test.

    24     24       set ch [open _diff_1 wb]
    25     25       puts -nonewline $ch $data1
    26     26       close $ch
    27     27       set ch [open _diff_2 wb]
    28     28       puts -nonewline $ch $data2
    29     29       close $ch
    30     30   
    31         -    set apa [catch {eval DiffUtil::compareFiles $args _diff_1 _diff_2} res]
           31  +    set apa [catch {DiffUtil::compareFiles {*}$args _diff_1 _diff_2} res]
    32     32       file delete -force _diff_1 _diff_2
    33     33       if {$apa} {
    34     34           return [list $apa $res]
    35     35       }
    36     36       return $res
    37     37   }
    38     38   
................................................................................
    61     61   } 0
    62     62   
    63     63   test comparefiles-1.5 {standard cases} {
    64     64       set l1 {abcd}
    65     65       set l2 {abce}
    66     66       RunTest $l1 $l2
    67     67   } 0
           68  +
           69  +test comparefiles-1.6 {standard cases} {
           70  +    set l1 {abcd}
           71  +    set l2 {abcD}
           72  +    list [RunTest $l1 $l2] [RunTest $l1 $l2 -nocase]
           73  +} {0 1}
    68     74   
    69     75   test comparefiles-2.1 {channel config} {CDiff} {
    70     76       set l1 {a b c}
    71     77       set l2 {a d c}
    72     78       RunTest $l1 $l2 -encoding iso8859-1 -translation lf
    73     79   } 0
    74     80   

Added undroid/DiffUtilTcl/tests/comparestreams.test.

            1  +# Tests for the 'DiffUtil' package. -*- tcl -*-
            2  +#
            3  +# Copyright (c) 2010 by Peter Spjuth. All rights reserved.
            4  +
            5  +package require DiffUtil
            6  +
            7  +if {[lsearch [namespace children] ::tcltest] == -1} {
            8  +    package require tcltest
            9  +    namespace import ::tcltest::*
           10  +}
           11  +
           12  +# There are differences between the C and the Diff result.
           13  +tcltest::testConstraint CDiff \
           14  +        [expr {[info proc DiffUtil::ExecDiffFiles] == ""}]
           15  +tcltest::testConstraint TclDiff \
           16  +        [expr {[info proc DiffUtil::ExecDiffFiles] != ""}]
           17  +
           18  +# All tests are for C only
           19  +if {[info proc DiffUtil::ExecDiffFiles] != ""} return
           20  +#----------------------------------------------------------------------
           21  +
           22  +# A wrapper to simplify calling
           23  +proc RunTest {data1 data2 args} {
           24  +    set ch [open _diff_1 wb]
           25  +    puts -nonewline $ch $data1
           26  +    close $ch
           27  +    set ch [open _diff_2 wb]
           28  +    puts -nonewline $ch $data2
           29  +    close $ch
           30  +
           31  +    set ch1 [open _diff_1 rb]
           32  +    set ch2 [open _diff_2 rb]
           33  +
           34  +    set apa [catch {DiffUtil::compareStreams {*}$args $ch1 $ch2} res]
           35  +    close $ch1
           36  +    close $ch2
           37  +    file delete -force _diff_1 _diff_2
           38  +    if {$apa} {
           39  +        return [list $apa $res]
           40  +    }
           41  +    return $res
           42  +}
           43  +
           44  +#----------------------------------------------------------------------
           45  +
           46  +test comparestreams-1.1 {standard cases} {
           47  +    set l1 {abcd}
           48  +    set l2 {abcd}
           49  +    RunTest $l1 $l2
           50  +} 1
           51  +
           52  +test comparestreams-1.2 {standard cases, error} -body {
           53  +    set l1 {a b c d   f g h i j k l}
           54  +    set l2 {  b c d e f g x y   k l}
           55  +    RunTest $l1 $l2 -hubba
           56  +} -result [list 1 {bad option "-hubba"*}] -match glob
           57  +
           58  +test comparestreams-1.3 {standard cases, error} -body {
           59  +    DiffUtil::compareStreams a
           60  +} -returnCodes 1 -result "wrong # args*" -match glob
           61  +
           62  +test comparestreams-1.4 {standard cases} {
           63  +    set l1 {abcd}
           64  +    set l2 {abcde}
           65  +    RunTest $l1 $l2
           66  +} 0
           67  +
           68  +test comparestreams-1.5 {standard cases} {
           69  +    set l1 {abcd}
           70  +    set l2 {abce}
           71  +    RunTest $l1 $l2
           72  +} 0
           73  +
           74  +test comparestreams-1.6 {standard cases} {
           75  +    set l1 {abcd}
           76  +    set l2 {abcD}
           77  +    list [RunTest $l1 $l2] [RunTest $l1 $l2 -nocase]
           78  +} {0 1}
           79  +
           80  +test comparestreams-2.1 {keywords} {
           81  +    set l1 {abcd}
           82  +    set l2 {abcD}
           83  +    list [RunTest $l1 $l2] [RunTest $l1 $l2 -ignorekey]
           84  +} {0 0}
           85  +
           86  +test comparestreams-2.2 {keywords} {
           87  +    set l1 {abcd $apa$}
           88  +    set l2 {abcd $apa: hej$}
           89  +    list [RunTest $l1 $l2] [RunTest $l1 $l2 -ignorekey]
           90  +} {0 1}
           91  +
           92  +test comparestreams-2.3 {keywords} {
           93  +    set l1 {abcd $apa::$}
           94  +    set l2 {abcd $apa: hej$}
           95  +    list [RunTest $l1 $l2] [RunTest $l1 $l2 -ignorekey]
           96  +} {0 1}
           97  +
           98  +test comparestreams-2.4 {keywords vs namespace vars} {
           99  +    set l1 {abcd $apa::hej$apa::hopp}
          100  +    set l2 {abcd $apa::haj$apa::hipp}
          101  +    list [RunTest $l1 $l2] [RunTest $l1 $l2 -ignorekey]
          102  +} {0 0}
          103  +
          104  +test comparestreams-2.5 {keywords} {
          105  +    set l1 {abcd $apa: hejsan$ hopp}
          106  +    set l2 {abcd $apa: hoppsan$ hopp}
          107  +    list [RunTest $l1 $l2] [RunTest $l1 $l2 -ignorekey]
          108  +} {0 1}
          109  +
          110  +test comparestreams-2.6 {keywords} {
          111  +    # Longer version of 2.5. Handle larger than block size.
          112  +    set l1 {abcd $apa: hejsan$ hopp}
          113  +    set l2 {abcd $apa: hoppsan$ hopp}
          114  +    append l1 [string repeat gurka 20000]
          115  +    append l2 [string repeat gurka 20000]
          116  +    list [RunTest $l1 $l2] [RunTest $l1 $l2 -ignorekey]
          117  +} {0 1}
          118  +
          119  +test comparestreams-2.7 {keywords} {
          120  +    set l1 {abcd $apa: hejsan$ hopp $bepa: hugo$ nej}
          121  +    set l2 {abcd $apa: hoppsan$ hopp $bepa: apa$ nej}
          122  +    list [RunTest $l1 $l2] [RunTest $l1 $l2 -ignorekey]
          123  +} {0 1}
          124  +
          125  +test comparestreams-2.8 {keywords} {
          126  +    set base1 {abcd $apa: hejsan$ hopp}
          127  +    set base2 {abcd $apa: hoppsan$ hopp}
          128  +    set lastOk 0
          129  +    # This will eventually fail when the keyword reaches the block size.
          130  +    for {set l 65500} {$l < 65540} {incr l} {
          131  +        set s1 [string repeat x $l]$base1
          132  +        set s2 [string repeat x $l]$base2
          133  +        if {[RunTest $s1 $s2 -ignorekey]} {
          134  +            set lastOk $l
          135  +        }
          136  +    }
          137  +    # Check that it worked long enough, but not too long
          138  +    expr {$lastOk > 65510 && $lastOk != 65539 ? 1 : $lastOk}
          139  +} {1}

Changes to undroid/DiffUtilTcl/tests/difffiles.test.

   415    415       set l2 {a \x82 c}
   416    416       list [RunTest $l1 $l2 -translation binary] [RunTest $l1 $l2 -encoding utf-8]
   417    417   } [list [list {2 1 2 1}] {}]
   418    418   
   419    419   test difffiles-12.1 {stack space bug} -body {
   420    420       # These files consume lots of candidate stack and crashed an earlier
   421    421       # version of diffUtil.
   422         -    DiffUtil::diffFiles -b tests/candbug1.txt tests/candbug2.txt
          422  +    DiffUtil::diffFiles -b [file join [configure -testdir] candbug1.txt] [file join [configure -testdir] candbug2.txt]
   423    423       return 0
   424    424   } -result {0}
   425    425   
   426    426   test difffiles-13.1 {long runtime bug} -constraints {CDiff} -body {
   427    427       # This case took very long time in an earlier version
   428    428       set l1 {}
   429    429       set l2 {}
................................................................................
   447    447           lappend l2 a b c d e f g h i j k l m n o p q r s t 
   448    448       }
   449    449       set result [RunTest $l1 $l2 -pivot 900]
   450    450   } -result {}
   451    451   
   452    452   test difffiles-14.1 {pivot bug} -constraints CDiff -body {
   453    453       # These files caused an error in post-processing of forbidden lines
   454         -    set x [DiffUtil::diffFiles -pivot 100 tests/pivot1.txt tests/pivot2.txt]
          454  +    set x [DiffUtil::diffFiles -pivot 100 [file join [configure -testdir] pivot1.txt] [file join [configure -testdir] pivot2.txt]]
   455    455       llength $x
   456    456   } -result {160}
   457    457   
   458    458   test difffiles-15.1a {forbidden stressing} -constraints {NoLcsDiff} -body {
   459    459       # Try to stress the postprocessing of forbidden matches
   460    460       # This is the result of diff and C without pivot
   461    461       set l1 {}

Changes to undroid/DiffUtilTcl/win/makefile.vc.

     1         -# makefile.vc --                                               -*- Makefile -*-
            1  +#------------------------------------------------------------- -*- makefile -*-
     2      2   #
     3         -# Microsoft Visual C++ makefile for use with nmake.exe v1.62+ (VC++ 5.0+)
            3  +# Makefile for diffutil
     4      4   #
     5         -# This makefile is based upon the Tcl 8.4 Makefile.vc and modified to 
     6         -# make it suitable as a general package makefile. Look for the word EDIT
     7         -# which marks sections that may need modification. As a minumum you will
     8         -# need to change the PROJECT, DOTVERSION and DLLOBJS variables to values
     9         -# relevant to your package.
            5  +# Basic build, test and install
            6  +#   nmake /f makefile.vc INSTALLDIR=c:\tcl
            7  +#   nmake /f makefile.vc INSTALLDIR=c:\tcl test
            8  +#   nmake /f makefile.vc INSTALLDIR=c:\tcl install
    10      9   #
           10  +# For other build options (debug, static etc.),
           11  +# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
           12  +# detailed documentation.
           13  +# 
    11     14   # See the file "license.terms" for information on usage and redistribution
    12     15   # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    13         -# 
    14         -# Copyright (c) 1995-1996 Sun Microsystems, Inc.
    15         -# Copyright (c) 1998-2000 Ajuba Solutions.
    16         -# Copyright (c) 2001 ActiveState Corporation.
    17         -# Copyright (c) 2001-2002 David Gravereaux.
    18         -# Copyright (c) 2003-2006 Pat Thoyts
    19         -#
    20         -#-------------------------------------------------------------------------
    21         -# RCS: @(#)$Id: makefile.vc,v 1.14 2010/09/14 23:23:32 hobbs Exp $
    22         -#-------------------------------------------------------------------------
    23         -
    24         -# Check to see we are configured to build with MSVC (MSDEVDIR or MSVCDIR)
    25         -# or with the MS Platform SDK (MSSDK). Visual Studio .NET 2003 and 2005 define
    26         -# VCINSTALLDIR instead. The MSVC Toolkit release defines yet another.
    27         -!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(MSSDK) && !defined(VCINSTALLDIR) && !defined(VCToolkitInstallDir)
    28         -MSG = ^
    29         -You need to run vcvars32.bat from Developer Studio or setenv.bat from the^
    30         -Platform SDK first to setup the environment.  Jump to this line to read^
    31         -the build instructions.
    32         -!error $(MSG)
    33         -!endif
    34         -
    35         -#------------------------------------------------------------------------------
    36         -# HOW TO USE this makefile:
    37         -#
    38         -# 1)  It is now necessary to have %MSVCDir% set in the environment.  This is
    39         -#     used  as a check to see if vcvars32.bat had been run prior to running
    40         -#     nmake or during the installation of Microsoft Visual C++, MSVCDir had
    41         -#     been set globally and the PATH adjusted.  Either way is valid.
    42         -#
    43         -#     You'll need to run vcvars32.bat contained in the MsDev's vc(98)/bin
    44         -#     directory to setup the proper environment, if needed, for your current
    45         -#     setup.  This is a needed bootstrap requirement and allows the swapping of
    46         -#     different environments to be easier.
    47         -#
    48         -# 2)  To use the Platform SDK (not expressly needed), run setenv.bat after
    49         -#     vcvars32.bat according to the instructions for it.  This can also turn on
    50         -#     the 64-bit compiler, if your SDK has it.
    51         -#
    52         -# 3)  Targets are:
    53         -#	all       -- Builds everything.
    54         -#       <project> -- Builds the project (eg: nmake sample)
    55         -#	test      -- Builds and runs the test suite.
    56         -#	install   -- Installs the built binaries and libraries to $(INSTALLDIR)
    57         -#		     in an appropriate subdirectory.
    58         -#	clean/realclean/distclean -- varying levels of cleaning.
    59         -#
    60         -# 4)  Macros usable on the commandline:
    61         -#	INSTALLDIR=<path>
    62         -#		Sets where to install Tcl from the built binaries.
    63         -#		C:\Progra~1\Tcl is assumed when not specified.
    64         -#
    65         -#	OPTS=static,msvcrt,staticpkg,threads,symbols,profile,loimpact,none
    66         -#		Sets special options for the core.  The default is for none.
    67         -#		Any combination of the above may be used (comma separated).
    68         -#		'none' will over-ride everything to nothing.
    69         -#
    70         -#		static  =  Builds a static library of the core instead of a
    71         -#			   dll.  The shell will be static (and large), as well.
    72         -#		msvcrt  =  Effects the static option only to switch it from
    73         -#			   using libcmt(d) as the C runtime [by default] to
    74         -#			   msvcrt(d). This is useful for static embedding
    75         -#			   support.
    76         -#		staticpkg = Effects the static option only to switch
    77         -#			   tclshXX.exe to have the dde and reg extension linked
    78         -#			   inside it.
    79         -#		nothreads = Turns off multithreading support (not recommended)
    80         -#		thrdalloc = Use the thread allocator (shared global free pool).
    81         -#		symbols =  Adds symbols for step debugging.
    82         -#		profile =  Adds profiling hooks.  Map file is assumed.
    83         -#		loimpact =  Adds a flag for how NT treats the heap to keep memory
    84         -#			   in use, low.  This is said to impact alloc performance.
    85         -#
    86         -#	STATS=memdbg,compdbg,none
    87         -#		Sets optional memory and bytecode compiler debugging code added
    88         -#		to the core.  The default is for none.  Any combination of the
    89         -#		above may be used (comma separated).  'none' will over-ride
    90         -#		everything to nothing.
    91         -#
    92         -#		memdbg   = Enables the debugging memory allocator.
    93         -#		compdbg  = Enables byte compilation logging.
    94         -#
    95         -#	MACHINE=(IX86|IA64|ALPHA|AMD64)
    96         -#		Set the machine type used for the compiler, linker, and
    97         -#		resource compiler.  This hook is needed to tell the tools
    98         -#		when alternate platforms are requested.  IX86 is the default
    99         -#		when not specified. If the CPU environment variable has been
   100         -#		set (ie: recent Platform SDK) then MACHINE is set from CPU.
   101         -#
   102         -#	TMP_DIR=<path>
   103         -#	OUT_DIR=<path>
   104         -#		Hooks to allow the intermediate and output directories to be
   105         -#		changed.  $(OUT_DIR) is assumed to be 
   106         -#		$(BINROOT)\(Release|Debug) based on if symbols are requested.
   107         -#		$(TMP_DIR) will de $(OUT_DIR)\<buildtype> by default.
   108         -#
   109         -#	TESTPAT=<file>
   110         -#		Reads the tests requested to be run from this file.
   111         -#
   112         -#	CFG_ENCODING=encoding
   113         -#		name of encoding for configuration information. Defaults
   114         -#		to cp1252
   115         -#
   116         -# 5)  Examples:
   117         -#
   118         -#	Basic syntax of calling nmake looks like this:
   119         -#	nmake [-nologo] -f makefile.vc [target|macrodef [target|macrodef] [...]]
   120         -#
   121         -#                        Standard (no frills)
   122         -#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
   123         -#       Setting environment for using Microsoft Visual C++ tools.
   124         -#       c:\tcl_src\win\>nmake -f makefile.vc all
   125         -#       c:\tcl_src\win\>nmake -f makefile.vc install INSTALLDIR=c:\progra~1\tcl
   126         -#
   127         -#                         Building for Win64
   128         -#       c:\tcl_src\win\>c:\progra~1\micros~1\vc98\bin\vcvars32.bat
   129         -#       Setting environment for using Microsoft Visual C++ tools.
   130         -#       c:\tcl_src\win\>c:\progra~1\platfo~1\setenv.bat /pre64 /RETAIL
   131         -#       Targeting Windows pre64 RETAIL
   132         -#       c:\tcl_src\win\>nmake -f makefile.vc MACHINE=IA64
   133     16   #
   134     17   #------------------------------------------------------------------------------
   135         -#==============================================================================
   136         -###############################################################################
   137         -#------------------------------------------------------------------------------
           18  +
           19  +
           20  +PROJECT = DiffUtil
   138     21   
   139         -!if !exist("makefile.vc")
   140         -MSG = ^
   141         -You must run this makefile only from the directory it is in.^
   142         -Please `cd` to its location first.
   143         -!error $(MSG)
   144         -!endif
           22  +!include "rules-ext.vc"
   145     23   
   146         -#-------------------------------------------------------------------------
   147         -# Project specific information (EDIT)
   148         -#
   149         -# You should edit this with the name and version of your project. This
   150         -# information is used to generate the name of the package library and
   151         -# it's install location.
   152         -#
   153         -# For example, the sample extension is  going to build sample05.dll and
   154         -# would install it into $(INSTALLDIR)\lib\sample05
   155         -#
   156         -# You need to specify the object files that need to be linked into your
   157         -# binary here.
   158         -#
   159         -#-------------------------------------------------------------------------
   160         -
   161         -PROJECT = diffutil
   162         -
   163         -# Uncomment the following line if this is a Tk extension.
   164         -#PROJECT_REQUIRES_TK=1
   165         -!include "rules.vc"
   166         -
   167         -DOTVERSION      = 0.4.0
   168         -VERSION         = $(DOTVERSION:.=)
   169         -STUBPREFIX      = $(PROJECT)stub
   170         -
   171         -DLLOBJS = \
           24  +PRJ_OBJS = \
   172     25   	$(TMP_DIR)\diffutil.obj \
   173     26   	$(TMP_DIR)\diff.obj \
   174         -!if !$(STATIC_BUILD)
   175         -	$(TMP_DIR)\diffutil.res
   176         -!endif
           27  +	$(TMP_DIR)\comparefiles.obj \
           28  +	$(TMP_DIR)\difffiles.obj \
           29  +	$(TMP_DIR)\difflists.obj \
           30  +	$(TMP_DIR)\diffstrings.obj
   177     31   
   178         -#-------------------------------------------------------------------------
   179         -# Target names and paths ( shouldn't need changing )
   180         -#-------------------------------------------------------------------------
           32  +# Hide numerous warnings of size_t to int conversions (4244) and
           33  +# signed/unsigned mismatch (4018) as these may cause genuine warnings
           34  +# to be missed
           35  +PRJ_DEFINES = -wd4244 -wd4018
   181     36   
   182         -BINROOT		= .
   183         -ROOT            = ..
   184         -
   185         -PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
   186         -PRJLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
   187         -PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)
           37  +!include "$(_RULESDIR)\targets.vc"
   188     38   
   189         -PRJSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
   190         -PRJSTUBLIB	= $(OUT_DIR)\$(PRJSTUBLIBNAME)
   191         -
   192         -### Make sure we use backslash only.
   193         -PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
   194         -LIB_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
   195         -BIN_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
   196         -DOC_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
   197         -SCRIPT_INSTALL_DIR	= $(PRJ_INSTALL_DIR)
   198         -INCLUDE_INSTALL_DIR	= $(_TCLDIR)\include
   199         -
   200         -### The following paths CANNOT have spaces in them.
   201         -GENERICDIR	= $(ROOT)\generic
   202         -WINDIR		= $(ROOT)\win
   203         -LIBDIR          = $(ROOT)\library
   204         -DOCDIR		= $(ROOT)\doc
   205         -TOOLSDIR	= $(ROOT)\tools
   206         -COMPATDIR	= $(ROOT)\compat
   207         -
   208         -#---------------------------------------------------------------------
   209         -# Compile flags
   210         -#---------------------------------------------------------------------
   211         -
   212         -!if !$(DEBUG)
   213         -!if $(OPTIMIZING)
   214         -### This cranks the optimization level to maximize speed
   215         -cdebug	= $(OPTIMIZATIONS)
   216         -!else
   217         -cdebug	=
   218         -!endif
   219         -!else if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
   220         -### Warnings are too many, can't support warnings into errors.
   221         -cdebug	= -Zi -Od $(DEBUGFLAGS)
   222         -!else
   223         -cdebug	= -Zi -WX $(DEBUGFLAGS)
   224         -!endif
   225         -
   226         -### Declarations common to all compiler options
   227         -cwarn = $(WARNINGS) -D _CRT_SECURE_NO_DEPRECATE -D _CRT_NONSTDC_NO_DEPRECATE
   228         -cflags = -nologo -c $(COMPILERFLAGS) -DBUILD_$(PROJECT) $(cwarn) -Fp$(TMP_DIR)^\
   229         -
   230         -!if $(MSVCRT)
   231         -!if $(DEBUG) && !$(UNCHECKED)
   232         -crt = -MDd
   233         -!else
   234         -crt = -MD
   235         -!endif
   236         -!else
   237         -!if $(DEBUG) && !$(UNCHECKED)
   238         -crt = -MTd
   239         -!else
   240         -crt = -MT
   241         -!endif
   242         -!endif
   243         -
   244         -!if !$(STATIC_BUILD)
   245         -cflags = $(cflags) -DUSE_TCL_STUBS
   246         -!if defined(TKSTUBLIB)
   247         -cflags = $(cflags) -DUSE_TK_STUBS
   248         -!endif
   249         -!endif
   250         -
   251         -INCLUDES	= $(TCL_INCLUDES) -I"$(WINDIR)" -I"$(GENERICDIR)"
   252         -BASE_CFLAGS	= $(cflags) $(cdebug) $(crt) $(INCLUDES)
   253         -CON_CFLAGS	= $(cflags) $(cdebug) $(crt) -DCONSOLE
   254         -TCL_CFLAGS	= -DPACKAGE_NAME="\"$(PROJECT)\"" \
   255         -		  -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
   256         -		  -DBUILD_$(PROJECT) \
   257         -		  $(BASE_CFLAGS) $(OPTDEFINES)
   258         -
   259         -#---------------------------------------------------------------------
   260         -# Link flags
   261         -#---------------------------------------------------------------------
   262         -
   263         -!if $(DEBUG)
   264         -ldebug	= -debug:full -debugtype:cv
   265         -!if $(MSVCRT)
   266         -ldebug = $(ldebug) -nodefaultlib:msvcrt
   267         -!endif
   268         -!else
   269         -ldebug	= -release -opt:ref -opt:icf,3
   270         -!endif
   271         -
   272         -### Declarations common to all linker options
   273         -lflags	= -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
   274         -
   275         -!if $(PROFILE)
   276         -lflags	= $(lflags) -profile
   277         -!endif
   278         -
   279         -!if $(ALIGN98_HACK) && !$(STATIC_BUILD)
   280         -### Align sections for PE size savings.
   281         -lflags	= $(lflags) -opt:nowin98
   282         -!else if !$(ALIGN98_HACK) && $(STATIC_BUILD)
   283         -### Align sections for speed in loading by choosing the virtual page size.
   284         -lflags	= $(lflags) -align:4096
   285         -!endif
   286         -
   287         -!if $(LOIMPACT)
   288         -lflags	= $(lflags) -ws:aggressive
   289         -!endif
   290         -
   291         -dlllflags = $(lflags) -dll
   292         -conlflags = $(lflags) -subsystem:console
   293         -guilflags = $(lflags) -subsystem:windows
   294         -!if !$(STATIC_BUILD)
   295         -baselibs  = $(TCLSTUBLIB)
   296         -!if defined(TKSTUBLIB)
   297         -baselibs  = $(baselibs) $(TKSTUBLIB)
   298         -!endif
   299         -!endif
   300         -
   301         -# Avoid 'unresolved external symbol __security_cookie' errors.
   302         -# c.f. http://support.microsoft.com/?id=894573
   303         -!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
   304         -!if $(VCVERSION) >= 1400 && $(VCVERSION) < 1500
   305         -baselibs   = $(baselibs) bufferoverflowU.lib
   306         -!endif
   307         -!endif
   308         -
   309         -baselibs   = $(baselibs) user32.lib gdi32.lib
   310         -
   311         -#---------------------------------------------------------------------
   312         -# TclTest flags
   313         -#---------------------------------------------------------------------
   314         -
   315         -!IF "$(TESTPAT)" != ""
   316         -TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
   317         -!ENDIF
   318         -
   319         -#---------------------------------------------------------------------
   320         -# Project specific targets (EDIT)
   321         -#---------------------------------------------------------------------
   322         -
   323         -all:	    setup $(PROJECT)
   324         -$(PROJECT): setup pkgIndex $(PRJLIB)
   325         -install:    install-binaries install-libraries install-docs
   326         -pkgIndex:   $(OUT_DIR)\pkgIndex.tcl
   327         -
   328         -test: setup $(PROJECT)
   329         -	@set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
   330         -	@set TCLLIBPATH=$(OUT_DIR_PATH:\=/)
   331         -!if $(TCLINSTALL)
   332         -	@set PATH=$(_TCLDIR)\bin;$(PATH)
   333         -!else
   334         -	@set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
   335         -!endif
   336         -!if "$(OS)" == "Windows_NT"  || "$(MSVCDIR)" == "IDE"
   337         -	$(DEBUGGER) $(TCLSH) "$(ROOT)/tests/all.tcl" $(TESTFLAGS)
   338         -!else
   339         -        @echo Please wait while the tests are collected...
   340         -        $(DEBUGGER) $(TCLSH) "$(ROOT)/tests/all.tcl" $(TESTFLAGS) > tests.log
   341         -	type tests.log | more
   342         -!endif
   343         -
   344         -shell: setup $(PROJECT)
   345         -	@set VLERQ_LIBRARY=$(LIBDIR:\=/)
   346         -	@set TCL_LIBRARY=$(TCL_LIBRARY:\=/)
   347         -	@set TCLLIBPATH=$(OUT_DIR_PATH:\=/)
   348         -!if $(TCLINSTALL)
   349         -	@set PATH=$(_TCLDIR)\bin;$(PATH)
   350         -!else
   351         -	@set PATH=$(_TCLDIR)\win\$(BUILDDIRTOP);$(PATH)
   352         -!endif
   353         -	$(DEBUGGER) $(TCLSH) $(SCRIPT)
   354         -
   355         -setup:
   356         -	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
   357         -	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
   358         -
   359         -# See <tcl>/win/coffbase.txt for extension base addresses.
   360         -$(PRJLIB): $(DLLOBJS)
   361         -!if $(STATIC_BUILD)
   362         -	$(lib32) -nologo -out:$@ @<<
   363         -$**
   364         -<<
   365         -!else
   366         -	$(link32) $(dlllflags) -base:0x10000000 -out:$@ $(baselibs) @<<
   367         -$**
   368         -<<
   369         -	$(_VC_MANIFEST_EMBED_DLL)
   370         -	-@del $*.exp
   371         -!endif
   372         -
   373         -$(PRJSTUBLIB): $(PRJSTUBOBJS)
   374         -	$(lib32) -nologo -out:$@ $(PRJSTUBOBJS)
   375         -
   376         -#---------------------------------------------------------------------
   377         -# Implicit rules
   378         -#---------------------------------------------------------------------
   379         -
   380         -{$(WINDIR)}.c{$(TMP_DIR)}.obj::
   381         -    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
   382         -$<
   383         -<<
   384         -
   385         -{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
   386         -    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
   387         -$<
   388         -<<
   389         -
   390         -{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
   391         -    $(cc32) $(TCL_CFLAGS) -DBUILD_$(PROJECT) -Fo$(TMP_DIR)\ @<<
   392         -$<
   393         -<<
   394         -
   395         -{$(WINDIR)}.rc{$(TMP_DIR)}.res:
   396         -	$(rc32) -fo $@ -r -i "$(GENERICDIR)" -D__WIN32__ \
   397         -		-DCOMMAVERSION=$(DOTVERSION:.=,),0,0 \
   398         -		-DDOTVERSION=\"$(DOTVERSION)\" \
   399         -		-DVERSION=\"$(VERSION)$(SUFX)\" \
   400         -!if $(DEBUG)
   401         -	-d DEBUG \
   402         -!endif
   403         -!if $(TCL_THREADS)
   404         -	-d TCL_THREADS \
   405         -!endif
   406         -!if $(STATIC_BUILD)
   407         -	-d STATIC_BUILD \
   408         -!endif
   409         -	$<
   410         -
   411         -.SUFFIXES:
   412         -.SUFFIXES:.c .rc
   413         -
   414         -#-------------------------------------------------------------------------
   415         -# Explicit dependency rules
   416         -#
   417         -#-------------------------------------------------------------------------
   418         -
   419         -$(OUT_DIR)\pkgIndex.tcl: $(ROOT)\pkgIndex.tcl.in
   420         -	@nmakehlp -s << $** > $@
   421         -@PACKAGE_VERSION@    $(DOTVERSION)
   422         -@PACKAGE_NAME@       $(PROJECT)
   423         -@PKG_LIB_FILE@       $(PRJLIBNAME)
   424         -<<
   425         -	@echo package ifneeded DiffUtil $(DOTVERSION) \
   426         -	    [list load [file join $$dir $(PRJLIBNAME)] Sample] >> $@
   427         -
   428         -#---------------------------------------------------------------------
   429         -# Installation. (EDIT)
   430         -#
   431         -# You may need to modify this section to reflect the final distribution
   432         -# of your files and possibly to generate documentation.
   433         -#
   434         -#---------------------------------------------------------------------
   435         -
   436         -install-binaries:
   437         -	@echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
   438         -	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
   439         -	@$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
   440         -
   441         -install-libraries: $(OUT_DIR)\pkgIndex.tcl
   442         -	@echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
   443         -	@if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
   444         -	@echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
   445         -	@$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
   446         -
   447         -install-docs:
   448         -	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
   449         -	@if exist $(DOCDIR) $(CPY) $(DOCDIR)\*.n "$(DOC_INSTALL_DIR)"
   450         -
   451         -#---------------------------------------------------------------------
   452         -# Clean up
   453         -#---------------------------------------------------------------------
   454         -
   455         -clean:
   456         -	@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
   457         -	@if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
   458         -	@if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
   459         -	@if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
   460         -	@if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
   461         -
   462         -realclean: clean
   463         -	@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
   464         -
   465         -distclean: realclean
   466         -	@if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
   467         -	@if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
           39  +install: default-install-docs-html
           40  +pkgindex: default-pkgindex-tea

Changes to undroid/DiffUtilTcl/win/nmakehlp.c.

     5      5    *	This is used to fix limitations within nmake and the environment.
     6      6    *
     7      7    * Copyright (c) 2002 by David Gravereaux.
     8      8    * Copyright (c) 2006 by Pat Thoyts
     9      9    *
    10     10    * See the file "license.terms" for information on usage and redistribution of
    11     11    * this file, and for a DISCLAIMER OF ALL WARRANTIES.
    12         - *
    13         - * ----------------------------------------------------------------------------
    14         - * RCS: @(#) $Id: nmakehlp.c,v 1.7 2008/06/18 11:01:42 patthoyts Exp $
    15     12    * ----------------------------------------------------------------------------
    16     13    */
    17     14   
    18     15   #define _CRT_SECURE_NO_DEPRECATE
    19     16   #include <windows.h>
    20     17   #define NO_SHLWAPI_GDI
    21     18   #define NO_SHLWAPI_STREAM
................................................................................
    38     35   
    39     36   /* ISO hack for dumb VC++ */
    40     37   #ifdef _MSC_VER
    41     38   #define   snprintf	_snprintf
    42     39   #endif
    43     40   
    44     41   
    45         -
    46     42   /* protos */
    47     43   
    48         -int		CheckForCompilerFeature(const char *option);
    49         -int		CheckForLinkerFeature(const char *option);
    50         -int		IsIn(const char *string, const char *substring);
    51         -int		GrepForDefine(const char *file, const char *string);
    52         -int		SubstituteFile(const char *substs, const char *filename);
    53         -int		QualifyPath(const char *path);
    54         -const char *    GetVersionFromFile(const char *filename, const char *match);
    55         -DWORD WINAPI	ReadFromPipe(LPVOID args);
           44  +static int CheckForCompilerFeature(const char *option);
           45  +static int CheckForLinkerFeature(const char **options, int count);
           46  +static int IsIn(const char *string, const char *substring);
           47  +static int SubstituteFile(const char *substs, const char *filename);
           48  +static int QualifyPath(const char *path);
           49  +static int LocateDependency(const char *keyfile);
           50  +static const char *GetVersionFromFile(const char *filename, const char *match, int numdots);
           51  +static DWORD WINAPI ReadFromPipe(LPVOID args);
    56     52   
    57     53   /* globals */
    58     54   
    59     55   #define CHUNK	25
    60     56   #define STATICBUFFERSIZE    1000
    61     57   typedef struct {
    62     58       HANDLE pipe;
................................................................................
    74     70   main(
    75     71       int argc,
    76     72       char *argv[])
    77     73   {
    78     74       char msg[300];
    79     75       DWORD dwWritten;
    80     76       int chars;
           77  +    char *s;
    81     78   
    82     79       /*
    83     80        * Make sure children (cl.exe and link.exe) are kept quiet.
    84     81        */
    85     82   
    86     83       SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
    87     84   
................................................................................
   102     99   			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
   103    100   		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
   104    101   			&dwWritten, NULL);
   105    102   		return 2;
   106    103   	    }
   107    104   	    return CheckForCompilerFeature(argv[2]);
   108    105   	case 'l':
   109         -	    if (argc != 3) {
          106  +	    if (argc < 3) {
   110    107   		chars = snprintf(msg, sizeof(msg) - 1,
   111         -	       		"usage: %s -l <linker option>\n"
          108  +	       		"usage: %s -l <linker option> ?<mandatory option> ...?\n"
   112    109   			"Tests for whether link.exe supports an option\n"
   113    110   			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
   114    111   		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
   115    112   			&dwWritten, NULL);
   116    113   		return 2;
   117    114   	    }
   118         -	    return CheckForLinkerFeature(argv[2]);
          115  +	    return CheckForLinkerFeature(&argv[2], argc-2);
   119    116   	case 'f':
   120    117   	    if (argc == 2) {
   121    118   		chars = snprintf(msg, sizeof(msg) - 1,
   122    119   			"usage: %s -f <string> <substring>\n"
   123    120   			"Find a substring within another\n"
   124    121   			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
   125    122   		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
................................................................................
   130    127   		 * If the string is blank, there is no match.
   131    128   		 */
   132    129   
   133    130   		return 0;
   134    131   	    } else {
   135    132   		return IsIn(argv[2], argv[3]);
   136    133   	    }
   137         -	case 'g':
   138         -	    if (argc == 2) {
   139         -		chars = snprintf(msg, sizeof(msg) - 1,
   140         -			"usage: %s -g <file> <string>\n"
   141         -			"grep for a #define\n"
   142         -			"exitcodes: integer of the found string (no decimals)\n",
   143         -			argv[0]);
   144         -		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
   145         -			&dwWritten, NULL);
   146         -		return 2;
   147         -	    }
   148         -	    return GrepForDefine(argv[2], argv[3]);
   149    134   	case 's':
   150    135   	    if (argc == 2) {
   151    136   		chars = snprintf(msg, sizeof(msg) - 1,
   152    137   			"usage: %s -s <substitutions file> <file>\n"
   153    138   			"Perform a set of string map type substutitions on a file\n"
   154    139   			"exitcodes: 0\n",
   155    140   			argv[0]);
................................................................................
   165    150   		    "Extract a version from a file:\n"
   166    151   		    "eg: pkgIndex.tcl \"package ifneeded http\"",
   167    152   		    argv[0]);
   168    153   		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
   169    154   		    &dwWritten, NULL);
   170    155   		return 0;
   171    156   	    }
   172         -	    printf("%s\n", GetVersionFromFile(argv[2], argv[3]));
   173         -	    return 0;
          157  +	    s = GetVersionFromFile(argv[2], argv[3], *(argv[1]+2) - '0');
          158  +	    if (s && *s) {
          159  +		printf("%s\n", s);
          160  +		return 0;
          161  +	    } else
          162  +		return 1; /* Version not found. Return non-0 exit code */
          163  +
   174    164   	case 'Q':
   175    165   	    if (argc != 3) {
   176    166   		chars = snprintf(msg, sizeof(msg) - 1,
   177         -		    "usage: %s -q path\n"
          167  +		    "usage: %s -Q path\n"
   178    168   		    "Emit the fully qualified path\n"
   179    169   		    "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
   180    170   		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
   181    171   		    &dwWritten, NULL);
   182    172   		return 2;
   183    173   	    }
   184    174   	    return QualifyPath(argv[2]);
          175  +
          176  +	case 'L':
          177  +	    if (argc != 3) {
          178  +		chars = snprintf(msg, sizeof(msg) - 1,
          179  +		    "usage: %s -L keypath\n"
          180  +		    "Emit the fully qualified path of directory containing keypath\n"
          181  +		    "exitcodes: 0 == success, 1 == not found, 2 == error\n", argv[0]);
          182  +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
          183  +		    &dwWritten, NULL);
          184  +		return 2;
          185  +	    }
          186  +	    return LocateDependency(argv[2]);
   185    187   	}
   186    188       }
   187    189       chars = snprintf(msg, sizeof(msg) - 1,
   188         -	    "usage: %s -c|-l|-f|-g|-V|-s|-Q ...\n"
          190  +	    "usage: %s -c|-f|-l|-Q|-s|-V ...\n"
   189    191   	    "This is a little helper app to equalize shell differences between WinNT and\n"
   190    192   	    "Win9x and get nmake.exe to accomplish its job.\n",
   191    193   	    argv[0]);
   192    194       WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
   193    195       return 2;
   194    196   }
   195    197   
   196         -int
          198  +static int
   197    199   CheckForCompilerFeature(
   198    200       const char *option)
   199    201   {
   200    202       STARTUPINFO si;
   201    203       PROCESS_INFORMATION pi;
   202    204       SECURITY_ATTRIBUTES sa;
   203    205       DWORD threadID;
................................................................................
   274    276   	DWORD err = GetLastError();
   275    277   	int chars = snprintf(msg, sizeof(msg) - 1,
   276    278   		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
   277    279   
   278    280   	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
   279    281   		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
   280    282   		(300-chars), 0);
   281         -	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
          283  +	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
   282    284   	return 2;
   283    285       }
   284    286   
   285    287       /*
   286    288        * Close our references to the write handles that have now been inherited.
   287    289        */
   288    290   
................................................................................
   323    325                || strstr(Err.buffer, "D4002") != NULL
   324    326                || strstr(Out.buffer, "D9002") != NULL
   325    327                || strstr(Err.buffer, "D9002") != NULL
   326    328                || strstr(Out.buffer, "D2021") != NULL
   327    329                || strstr(Err.buffer, "D2021") != NULL);
   328    330   }
   329    331   
   330         -int
          332  +static int
   331    333   CheckForLinkerFeature(
   332         -    const char *option)
          334  +    const char **options,
          335  +    int count)
   333    336   {
   334    337       STARTUPINFO si;
   335    338       PROCESS_INFORMATION pi;
   336    339       SECURITY_ATTRIBUTES sa;
   337    340       DWORD threadID;
   338    341       char msg[300];
   339    342       BOOL ok;
   340    343       HANDLE hProcess, h, pipeThreads[2];
   341         -    char cmdline[100];
          344  +    int i;
          345  +    char cmdline[255];
   342    346   
   343    347       hProcess = GetCurrentProcess();
   344    348   
   345    349       ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
   346    350       ZeroMemory(&si, sizeof(STARTUPINFO));
   347    351       si.cb = sizeof(STARTUPINFO);
   348    352       si.dwFlags   = STARTF_USESTDHANDLES;
................................................................................
   380    384   
   381    385       lstrcpy(cmdline, "link.exe -nologo ");
   382    386   
   383    387       /*
   384    388        * Append our option for testing.
   385    389        */
   386    390   
   387         -    lstrcat(cmdline, option);
          391  +    for (i = 0; i < count; i++) {
          392  +	lstrcat(cmdline, " \"");
          393  +	lstrcat(cmdline, options[i]);
          394  +	lstrcat(cmdline, "\"");
          395  +    }
   388    396   
   389    397       ok = CreateProcess(
   390    398   	    NULL,	    /* Module name. */
   391    399   	    cmdline,	    /* Command line. */
   392    400   	    NULL,	    /* Process handle not inheritable. */
   393    401   	    NULL,	    /* Thread handle not inheritable. */
   394    402   	    TRUE,	    /* yes, inherit handles. */
................................................................................
   402    410   	DWORD err = GetLastError();
   403    411   	int chars = snprintf(msg, sizeof(msg) - 1,
   404    412   		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
   405    413   
   406    414   	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
   407    415   		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
   408    416   		(300-chars), 0);
   409         -	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg,lstrlen(msg), &err,NULL);
          417  +	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
   410    418   	return 2;
   411    419       }
   412    420   
   413    421       /*
   414    422        * Close our references to the write handles that have now been inherited.
   415    423        */
   416    424   
................................................................................
   445    453       /*
   446    454        * Look for the commandline warning code in the stderr stream.
   447    455        */
   448    456   
   449    457       return !(strstr(Out.buffer, "LNK1117") != NULL ||
   450    458   	    strstr(Err.buffer, "LNK1117") != NULL ||
   451    459   	    strstr(Out.buffer, "LNK4044") != NULL ||
   452         -	    strstr(Err.buffer, "LNK4044") != NULL);
          460  +	    strstr(Err.buffer, "LNK4044") != NULL ||
          461  +	    strstr(Out.buffer, "LNK4224") != NULL ||
          462  +	    strstr(Err.buffer, "LNK4224") != NULL);
   453    463   }
   454    464   
   455         -DWORD WINAPI
          465  +static DWORD WINAPI
   456    466   ReadFromPipe(
   457    467       LPVOID args)
   458    468   {
   459    469       pipeinfo *pi = (pipeinfo *) args;
   460    470       char *lastBuf = pi->buffer;
   461    471       DWORD dwRead;
   462    472       BOOL ok;
................................................................................
   473    483       }
   474    484       lastBuf += dwRead;
   475    485       goto again;
   476    486   
   477    487       return 0;  /* makes the compiler happy */
   478    488   }
   479    489   
   480         -int
          490  +static int
   481    491   IsIn(
   482    492       const char *string,
   483    493       const char *substring)
   484    494   {
   485    495       return (strstr(string, substring) != NULL);
   486    496   }
   487         -
   488         -/*
   489         - * Find a specified #define by name.
   490         - *
   491         - * If the line is '#define TCL_VERSION "8.5"', it returns 85 as the result.
   492         - */
   493         -
   494         -int
   495         -GrepForDefine(
   496         -    const char *file,
   497         -    const char *string)
   498         -{
   499         -    char s1[51], s2[51], s3[51];
   500         -    FILE *f = fopen(file, "rt");
   501         -
   502         -    if (f == NULL) {
   503         -	return 0;
   504         -    }
   505         -
   506         -    do {
   507         -	int r = fscanf(f, "%50s", s1);
   508         -
   509         -	if (r == 1 && !strcmp(s1, "#define")) {
   510         -	    /*
   511         -	     * Get next two words.
   512         -	     */
   513         -
   514         -	    r = fscanf(f, "%50s %50s", s2, s3);
   515         -	    if (r != 2) {
   516         -		continue;
   517         -	    }
   518         -
   519         -	    /*
   520         -	     * Is the first word what we're looking for?
   521         -	     */
   522         -
   523         -	    if (!strcmp(s2, string)) {
   524         -		double d1;
   525         -
   526         -		fclose(f);
   527         -
   528         -		/*
   529         -		 * Add 1 past first double quote char. "8.5"
   530         -		 */
   531         -
   532         -		d1 = atof(s3 + 1);		  /*    8.5  */
   533         -		while (floor(d1) != d1) {
   534         -		    d1 *= 10.0;
   535         -		}
   536         -		return ((int) d1);		  /*    85   */
   537         -	    }
   538         -	}
   539         -    } while (!feof(f));
   540         -
   541         -    fclose(f);
   542         -    return 0;
   543         -}
   544    497   
   545    498   /*
   546    499    * GetVersionFromFile --
   547    500    * 	Looks for a match string in a file and then returns the version
   548    501    * 	following the match where a version is anything acceptable to
   549    502    * 	package provide or package ifneeded.
   550    503    */
   551    504   
   552         -const char *
          505  +static const char *
   553    506   GetVersionFromFile(
   554    507       const char *filename,
   555         -    const char *match)
          508  +    const char *match,
          509  +    int numdots)
   556    510   {
   557    511       size_t cbBuffer = 100;
   558    512       static char szBuffer[100];
   559    513       char *szResult = NULL;
   560    514       FILE *fp = fopen(filename, "rt");
   561    515   
   562    516       if (fp != NULL) {
................................................................................
   566    520   
   567    521   	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
   568    522   	    LPSTR p, q;
   569    523   
   570    524   	    p = strstr(szBuffer, match);
   571    525   	    if (p != NULL) {
   572    526   		/*
   573         -		 * Skip to first digit.
          527  +		 * Skip to first digit after the match.
   574    528   		 */
   575    529   
          530  +		p += strlen(match);
   576    531   		while (*p && !isdigit(*p)) {
   577    532   		    ++p;
   578    533   		}
   579    534   
   580    535   		/*
   581    536   		 * Find ending whitespace.
   582    537   		 */
   583    538   
   584    539   		q = p;
   585         -		while (*q && (isalnum(*q) || *q == '.')) {
          540  +		while (*q && (strchr("0123456789.ab", *q)) && ((!strchr(".ab", *q)
          541  +			    && (!strchr("ab", q[-1])) || --numdots))) {
   586    542   		    ++q;
   587    543   		}
   588    544   
   589    545   		memcpy(szBuffer, p, q - p);
   590    546   		szBuffer[q-p] = 0;
   591    547   		szResult = szBuffer;
   592    548   		break;
................................................................................
   651    607    *	Usage is something like:
   652    608    *	  nmakehlp -S << $** > $@
   653    609    *        @PACKAGE_NAME@ $(PACKAGE_NAME)
   654    610    *        @PACKAGE_VERSION@ $(PACKAGE_VERSION)
   655    611    *        <<
   656    612    */
   657    613   
   658         -int
          614  +static int
   659    615   SubstituteFile(
   660    616       const char *substitutions,
   661    617       const char *filename)
   662    618   {
   663    619       size_t cbBuffer = 1024;
   664    620       static char szBuffer[1024], szCopy[1024];
   665    621       char *szResult = NULL;
................................................................................
   672    628   	/*
   673    629   	 * Build a list of substutitions from the first filename
   674    630   	 */
   675    631   
   676    632   	sp = fopen(substitutions, "rt");
   677    633   	if (sp != NULL) {
   678    634   	    while (fgets(szBuffer, cbBuffer, sp) != NULL) {
   679         -		char *ks, *ke, *vs, *ve;
   680         -		ks = szBuffer;
          635  +		unsigned char *ks, *ke, *vs, *ve;
          636  +		ks = (unsigned char*)szBuffer;
   681    637   		while (ks && *ks && isspace(*ks)) ++ks;
   682    638   		ke = ks;
   683    639   		while (ke && *ke && !isspace(*ke)) ++ke;
   684    640   		vs = ke;
   685    641   		while (vs && *vs && isspace(*vs)) ++vs;
   686    642   		ve = vs;
   687    643   		while (ve && *ve && !(*ve == '\r' || *ve == '\n')) ++ve;
   688    644   		*ke = 0, *ve = 0;
   689         -		list_insert(&substPtr, ks, vs);
          645  +		list_insert(&substPtr, (char*)ks, (char*)vs);
   690    646   	    }
   691    647   	    fclose(sp);
   692    648   	}
   693    649   
   694    650   	/* debug: dump the list */
   695    651   #ifdef _DEBUG
   696    652   	{
................................................................................
   697    653   	    int n = 0;
   698    654   	    list_item_t *p = NULL;
   699    655   	    for (p = substPtr; p != NULL; p = p->nextPtr, ++n) {
   700    656   		fprintf(stderr, "% 3d '%s' => '%s'\n", n, p->key, p->value);
   701    657   	    }
   702    658   	}
   703    659   #endif
   704         -	
          660  +
   705    661   	/*
   706    662   	 * Run the substitutions over each line of the input
   707    663   	 */
   708         -	
          664  +
   709    665   	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
   710    666   	    list_item_t *p = NULL;
   711    667   	    for (p = substPtr; p != NULL; p = p->nextPtr) {
   712    668   		char *m = strstr(szBuffer, p->key);
   713    669   		if (m) {
   714    670   		    char *cp, *op, *sp;
   715    671   		    cp = szCopy;
................................................................................
   721    677   		    while (*op) *cp++ = *op++;
   722    678   		    *cp = 0;
   723    679   		    memcpy(szBuffer, szCopy, sizeof(szCopy));
   724    680   		}
   725    681   	    }
   726    682   	    printf(szBuffer);
   727    683   	}
   728         -	
          684  +
   729    685   	list_free(&substPtr);
   730    686       }
   731    687       fclose(fp);
   732    688       return 0;
   733    689   }
   734    690   
   735    691   /*
................................................................................
   736    692    * QualifyPath --
   737    693    *
   738    694    *	This composes the current working directory with a provided path
   739    695    *	and returns the fully qualified and normalized path.
   740    696    *	Mostly needed to setup paths for testing.
   741    697    */
   742    698   
   743         -int
          699  +static int
   744    700   QualifyPath(
   745    701       const char *szPath)
   746    702   {
   747    703       char szCwd[MAX_PATH + 1];
   748    704       char szTmp[MAX_PATH + 1];
   749    705       char *p;
   750    706       GetCurrentDirectory(MAX_PATH, szCwd);
................................................................................
   751    707       while ((p = strchr(szPath, '/')) && *p)
   752    708   	*p = '\\';
   753    709       PathCombine(szTmp, szCwd, szPath);
   754    710       PathCanonicalize(szCwd, szTmp);
   755    711       printf("%s\n", szCwd);
   756    712       return 0;
   757    713   }
          714  +
          715  +/*
          716  + * Implements LocateDependency for a single directory. See that command
          717  + * for an explanation.
          718  + * Returns 0 if found after printing the directory.
          719  + * Returns 1 if not found but no errors.
          720  + * Returns 2 on any kind of error
          721  + * Basically, these are used as exit codes for the process.
          722  + */
          723  +static int LocateDependencyHelper(const char *dir, const char *keypath)
          724  +{
          725  +    HANDLE hSearch;
          726  +    char path[MAX_PATH+1];
          727  +    int dirlen, keylen, ret;
          728  +    WIN32_FIND_DATA finfo;
          729  +
          730  +    if (dir == NULL || keypath == NULL)
          731  +	return 2; /* Have no real error reporting mechanism into nmake */
          732  +    dirlen = strlen(dir);
          733  +    if ((dirlen + 3) > sizeof(path))
          734  +	return 2;
          735  +    strncpy(path, dir, dirlen);
          736  +    strncpy(path+dirlen, "\\*", 3);	/* Including terminating \0 */
          737  +    keylen = strlen(keypath);
          738  +
          739  +#if 0 /* This function is not available in Visual C++ 6 */
          740  +    /*
          741  +     * Use numerics 0 -> FindExInfoStandard,
          742  +     * 1 -> FindExSearchLimitToDirectories, 
          743  +     * as these are not defined in Visual C++ 6
          744  +     */
          745  +    hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0);
          746  +#else
          747  +    hSearch = FindFirstFile(path, &finfo);
          748  +#endif
          749  +    if (hSearch == INVALID_HANDLE_VALUE)
          750  +	return 1; /* Not found */
          751  +
          752  +    /* Loop through all subdirs checking if the keypath is under there */
          753  +    ret = 1; /* Assume not found */
          754  +    do {
          755  +	int sublen;
          756  +	/*
          757  +	 * We need to check it is a directory despite the 
          758  +	 * FindExSearchLimitToDirectories in the above call. See SDK docs
          759  +	 */
          760  +	if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
          761  +	    continue;
          762  +	sublen = strlen(finfo.cFileName);
          763  +	if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
          764  +	    continue;		/* Path does not fit, assume not matched */
          765  +	strncpy(path+dirlen+1, finfo.cFileName, sublen);
          766  +	path[dirlen+1+sublen] = '\\';
          767  +	strncpy(path+dirlen+1+sublen+1, keypath, keylen+1);
          768  +	if (PathFileExists(path)) {
          769  +	    /* Found a match, print to stdout */
          770  +	    path[dirlen+1+sublen] = '\0';
          771  +	    QualifyPath(path);
          772  +	    ret = 0;
          773  +	    break;
          774  +	}
          775  +    } while (FindNextFile(hSearch, &finfo));
          776  +    FindClose(hSearch);
          777  +    return ret;
          778  +}
          779  +
          780  +/*
          781  + * LocateDependency --
          782  + *
          783  + *	Locates a dependency for a package.
          784  + *        keypath - a relative path within the package directory
          785  + *          that is used to confirm it is the correct directory.
          786  + *	The search path for the package directory is currently only
          787  + *      the parent and grandparent of the current working directory.
          788  + *      If found, the command prints 
          789  + *         name_DIRPATH=<full path of located directory>
          790  + *      and returns 0. If not found, does not print anything and returns 1.
          791  + */
          792  +static int LocateDependency(const char *keypath)
          793  +{
          794  +    int i, ret;
          795  +    static char *paths[] = {"..", "..\\..", "..\\..\\.."};
          796  +    
          797  +    for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
          798  +	ret = LocateDependencyHelper(paths[i], keypath);
          799  +	if (ret == 0)
          800  +	    return ret;
          801  +    }
          802  +    return ret;
          803  +}
          804  +
   758    805   
   759    806   /*
   760    807    * Local variables:
   761    808    *   mode: c
   762    809    *   c-basic-offset: 4
   763    810    *   fill-column: 78
   764    811    *   indent-tabs-mode: t
   765    812    *   tab-width: 8
   766    813    * End:
   767    814    */

Added undroid/DiffUtilTcl/win/rules-ext.vc.

            1  +# This file should only be included in makefiles for Tcl extensions,
            2  +# NOT in the makefile for Tcl itself.
            3  +
            4  +!ifndef _RULES_EXT_VC
            5  +
            6  +# We need to run from the directory the parent makefile is located in.
            7  +# nmake does not tell us what makefile was used to invoke it so parent
            8  +# makefile has to set the MAKEFILEVC macro or we just make a guess and
            9  +# warn if we think that is not the case.
           10  +!if "$(MAKEFILEVC)" == ""
           11  +
           12  +!if exist("$(PROJECT).vc")
           13  +MAKEFILEVC = $(PROJECT).vc
           14  +!elseif exist("makefile.vc")
           15  +MAKEFILEVC = makefile.vc
           16  +!endif
           17  +!endif # "$(MAKEFILEVC)" == ""
           18  +
           19  +!if !exist("$(MAKEFILEVC)")
           20  +MSG = ^
           21  +You must run nmake from the directory containing the project makefile.^
           22  +If you are doing that and getting this message, set the MAKEFILEVC^
           23  +macro to the name of the project makefile.
           24  +!message WARNING: $(MSG)
           25  +!endif
           26  +
           27  +!if "$(PROJECT)" == "tcl"
           28  +!error The rules-ext.vc file is not intended for Tcl itself.
           29  +!endif
           30  +
           31  +# We extract version numbers using the nmakehlp program. For now use
           32  +# the local copy of nmakehlp. Once we locate Tcl, we will use that
           33  +# one if it is newer.
           34  +!if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul]
           35  +!endif
           36  +
           37  +# First locate the Tcl directory that we are working with.
           38  +!if "$(TCLDIR)" != ""
           39  +
           40  +_RULESDIR = $(TCLDIR:/=\)
           41  +
           42  +!else
           43  +
           44  +# If an installation path is specified, that is also the Tcl directory.
           45  +# Also Tk never builds against an installed Tcl, it needs Tcl sources
           46  +!if defined(INSTALLDIR) && "$(PROJECT)" != "tk"
           47  +_RULESDIR=$(INSTALLDIR:/=\)
           48  +!else
           49  +# Locate Tcl sources
           50  +!if [echo _RULESDIR = \> nmakehlp.out] \
           51  +   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
           52  +_RULESDIR = ..\..\tcl
           53  +!else
           54  +!include nmakehlp.out
           55  +!endif
           56  +
           57  +!endif # defined(INSTALLDIR)....
           58  +
           59  +!endif # ifndef TCLDIR
           60  +
           61  +# Now look for the targets.vc file under the Tcl root. Note we check this
           62  +# file and not rules.vc because the latter also exists on older systems.
           63  +!if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl
           64  +_RULESDIR = $(_RULESDIR)\lib\nmake
           65  +!elseif exist("$(_RULESDIR)\win\targets.vc")   # Building against Tcl sources
           66  +_RULESDIR = $(_RULESDIR)\win
           67  +!else
           68  +# If we have not located Tcl's targets file, most likely we are compiling
           69  +# against an older version of Tcl and so must use our own support files.
           70  +_RULESDIR = .
           71  +!endif
           72  +
           73  +!if "$(_RULESDIR)" != "."
           74  +# Potentially using Tcl's support files. If this extension has its own
           75  +# nmake support files, need to compare the versions and pick newer.
           76  +
           77  +!if exist("rules.vc") # The extension has its own copy
           78  +
           79  +!if [echo TCL_RULES_MAJOR = \> versions.vc] \
           80  +   && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc]
           81  +!endif
           82  +!if [echo TCL_RULES_MINOR = \>> versions.vc] \
           83  +   && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc]
           84  +!endif
           85  +
           86  +!if [echo OUR_RULES_MAJOR = \>> versions.vc] \
           87  +   && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc]
           88  +!endif
           89  +!if [echo OUR_RULES_MINOR = \>> versions.vc] \
           90  +   && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc]
           91  +!endif
           92  +!include versions.vc
           93  +# We have a newer version of the support files, use them
           94  +!if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR))
           95  +_RULESDIR = .
           96  +!endif
           97  +
           98  +!endif # if exist("rules.vc")
           99  +
          100  +!endif # if $(_RULESDIR) != "."
          101  +
          102  +# Let rules.vc know what copy of nmakehlp.c to use.
          103  +NMAKEHLPC = $(_RULESDIR)\nmakehlp.c
          104  +
          105  +# Get rid of our internal defines before calling rules.vc
          106  +!undef TCL_RULES_MAJOR
          107  +!undef TCL_RULES_MINOR
          108  +!undef OUR_RULES_MAJOR
          109  +!undef OUR_RULES_MINOR
          110  +
          111  +!if exist("$(_RULESDIR)\rules.vc")
          112  +!message *** Using $(_RULESDIR)\rules.vc
          113  +!include "$(_RULESDIR)\rules.vc"
          114  +!else
          115  +!error *** Could not locate rules.vc in $(_RULESDIR)
          116  +!endif
          117  +
          118  +!endif # _RULES_EXT_VC

Changes to undroid/DiffUtilTcl/win/rules.vc.

     1         -#------------------------------------------------------------- -*- Makefile -*-
            1  +#------------------------------------------------------------- -*- makefile -*-
     2      2   # rules.vc --
     3      3   #
     4         -#	Microsoft Visual C++ makefile include for decoding the commandline
     5         -#	macros.  This file does not need editing to build Tcl.
            4  +# Part of the nmake based build system for Tcl and its extensions.
            5  +# This file does all the hard work in terms of parsing build options,
            6  +# compiler switches, defining common targets and macros. The Tcl makefile
            7  +# directly includes this. Extensions include it via "rules-ext.vc".
     6      8   #
     7         -#	This version is modified from the Tcl source version to support
     8         -#	building extensions using nmake.
            9  +# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for
           10  +# detailed documentation.
     9     11   #
    10     12   # See the file "license.terms" for information on usage and redistribution
    11     13   # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    12         -# 
    13         -# Copyright (c) 2001-2002 David Gravereaux.
           14  +#
           15  +# Copyright (c) 2001-2003 David Gravereaux.
    14     16   # Copyright (c) 2003-2008 Patrick Thoyts
    15         -#
    16         -#------------------------------------------------------------------------------
    17         -# RCS: @(#) $Id: rules.vc,v 1.9 2009/05/04 23:47:55 patthoyts Exp $
           17  +# Copyright (c) 2017      Ashok P. Nadkarni
    18     18   #------------------------------------------------------------------------------
    19     19   
    20     20   !ifndef _RULES_VC
    21     21   _RULES_VC = 1
    22     22   
    23         -cc32		= $(CC)   # built-in default.
    24         -link32		= link
    25         -lib32		= lib
    26         -rc32		= $(RC)   # built-in default.
    27         -
    28         -!ifndef INSTALLDIR
    29         -### Assume the normal default.
    30         -_INSTALLDIR	= C:\Program Files\Tcl
    31         -!else
    32         -### Fix the path separators.
    33         -_INSTALLDIR	= $(INSTALLDIR:/=\)
    34         -!endif
    35         -
    36         -!ifndef MACHINE
    37         -!if "$(CPU)" == "" || "$(CPU)" == "i386"
    38         -MACHINE         = IX86
    39         -!else
    40         -MACHINE         = $(CPU)
    41         -!endif
    42         -!endif
    43         -
    44         -!ifndef CFG_ENCODING
    45         -CFG_ENCODING	= \"cp1252\"
    46         -!endif
           23  +# The following macros define the version of the rules.vc nmake build system
           24  +# For modifications that are not backward-compatible, you *must* change
           25  +# the major version.
           26  +RULES_VERSION_MAJOR = 1
           27  +RULES_VERSION_MINOR = 1
           28  +
           29  +# The PROJECT macro must be defined by parent makefile.
           30  +!if "$(PROJECT)" == ""
           31  +!error *** Error: Macro PROJECT not defined! Please define it before including rules.vc
           32  +!endif
           33  +
           34  +!if "$(PRJ_PACKAGE_TCLNAME)" == ""
           35  +PRJ_PACKAGE_TCLNAME = $(PROJECT)
           36  +!endif
           37  +
           38  +# Also special case Tcl and Tk to save some typing later
           39  +DOING_TCL = 0
           40  +DOING_TK  = 0
           41  +!if "$(PROJECT)" == "tcl"
           42  +DOING_TCL = 1
           43  +!elseif "$(PROJECT)" == "tk"
           44  +DOING_TK = 1
           45  +!endif
           46  +
           47  +!ifndef NEED_TK
           48  +# Backwards compatibility
           49  +!ifdef PROJECT_REQUIRES_TK
           50  +NEED_TK = $(PROJECT_REQUIRES_TK)
           51  +!else
           52  +NEED_TK = 0
           53  +!endif
           54  +!endif
           55  +
           56  +!ifndef NEED_TCL_SOURCE
           57  +NEED_TCL_SOURCE = 0
           58  +!endif
           59  +
           60  +!ifdef NEED_TK_SOURCE
           61  +!if $(NEED_TK_SOURCE)
           62  +NEED_TK = 1
           63  +!endif
           64  +!else
           65  +NEED_TK_SOURCE = 0
           66  +!endif
           67  +
           68  +################################################################
           69  +# Nmake is a pretty weak environment in syntax and capabilities
           70  +# so this file is necessarily verbose. It's broken down into
           71  +# the following parts.
           72  +#
           73  +# 0. Sanity check that compiler environment is set up and initialize
           74  +#    any built-in settings from the parent makefile
           75  +# 1. First define the external tools used for compiling, copying etc.
           76  +#    as this is independent of everything else.
           77  +# 2. Figure out our build structure in terms of the directory, whether
           78  +#    we are building Tcl or an extension, etc.
           79  +# 3. Determine the compiler and linker versions
           80  +# 4. Build the nmakehlp helper application
           81  +# 5. Determine the supported compiler options and features
           82  +# 6. Parse the OPTS macro value for user-specified build configuration
           83  +# 7. Parse the STATS macro value for statistics instrumentation
           84  +# 8. Parse the CHECKS macro for additional compilation checks
           85  +# 9. Extract Tcl, and possibly Tk, version numbers from the headers
           86  +# 10. Based on this selected configuration, construct the output
           87  +#     directory and file paths
           88  +# 11. Construct the paths where the package is to be installed
           89  +# 12. Set up the actual options passed to compiler and linker based
           90  +#     on the information gathered above.
           91  +# 13. Define some standard build targets and implicit rules. These may
           92  +#     be optionally disabled by the parent makefile.
           93  +# 14. (For extensions only.) Compare the configuration of the target
           94  +#     Tcl and the extensions and warn against discrepancies.
           95  +#
           96  +# One final note about the macro names used. They are as they are
           97  +# for historical reasons. We would like legacy extensions to
           98  +# continue to work with this make include file so be wary of
           99  +# changing them for consistency or clarity.
          100  +
          101  +# 0. Sanity check compiler environment
          102  +
          103  +# Check to see we are configured to build with MSVC (MSDEVDIR, MSVCDIR or
          104  +# VCINSTALLDIR) or with the MS Platform SDK (MSSDK or WindowsSDKDir)
          105  +
          106  +!if !defined(MSDEVDIR) && !defined(MSVCDIR) && !defined(VCINSTALLDIR) && !defined(MSSDK) && !defined(WINDOWSSDKDIR)
          107  +MSG = ^
          108  +Visual C++ compiler environment not initialized.
          109  +!error $(MSG)
          110  +!endif
          111  +
          112  +# We need to run from the directory the parent makefile is located in.
          113  +# nmake does not tell us what makefile was used to invoke it so parent
          114  +# makefile has to set the MAKEFILEVC macro or we just make a guess and
          115  +# warn if we think that is not the case.
          116  +!if "$(MAKEFILEVC)" == ""
          117  +
          118  +!if exist("$(PROJECT).vc")
          119  +MAKEFILEVC = $(PROJECT).vc
          120  +!elseif exist("makefile.vc")
          121  +MAKEFILEVC = makefile.vc
          122  +!endif
          123  +!endif # "$(MAKEFILEVC)" == ""
          124  +
          125  +!if !exist("$(MAKEFILEVC)")
          126  +MSG = ^
          127  +You must run nmake from the directory containing the project makefile.^
          128  +If you are doing that and getting this message, set the MAKEFILEVC^
          129  +macro to the name of the project makefile.
          130  +!message WARNING: $(MSG)
          131  +!endif
          132  +
          133  +
          134  +################################################################
          135  +# 1. Define external programs being used
    47    136   
    48    137   #----------------------------------------------------------
    49    138   # Set the proper copy method to avoid overwrite questions
    50    139   # to the user when copying files and selecting the right
    51    140   # "delete all" method.
    52    141   #----------------------------------------------------------
    53    142   
    54         -!if "$(OS)" == "Windows_NT"
    55    143   RMDIR	= rmdir /S /Q
    56         -ERRNULL  = 2>NUL
    57         -!if ![ver | find "4.0" > nul]
    58         -CPY	= echo y | xcopy /i >NUL
    59         -COPY	= copy >NUL
    60         -!else
    61    144   CPY	= xcopy /i /y >NUL
          145  +CPYDIR  = xcopy /e /i /y >NUL
    62    146   COPY	= copy /y >NUL
    63         -!endif
    64         -!else # "$(OS)" != "Windows_NT"
    65         -CPY	= xcopy /i >_JUNK.OUT # On Win98 NUL does not work here.
    66         -COPY	= copy >_JUNK.OUT # On Win98 NUL does not work here.
    67         -RMDIR	= deltree /Y
    68         -NULL    = \NUL # Used in testing directory existence
    69         -ERRNULL = >NUL # Win9x shell cannot redirect stderr
    70         -!endif
    71    147   MKDIR   = mkdir
    72    148   
    73         -!message ===============================================================================
    74         -
    75         -#----------------------------------------------------------
    76         -# build the helper app we need to overcome nmake's limiting
    77         -# environment.
    78         -#----------------------------------------------------------
    79         -
    80         -!if !exist(nmakehlp.exe)
    81         -!if [$(cc32) -nologo nmakehlp.c -link -subsystem:console > nul]
    82         -!endif
    83         -!endif
    84         -
    85         -#----------------------------------------------------------
    86         -# Test for compiler features
    87         -#----------------------------------------------------------
    88         -
    89         -### test for optimizations
    90         -!if [nmakehlp -c -Ot]
    91         -!message *** Compiler has 'Optimizations'
    92         -OPTIMIZING	= 1
    93         -!else
    94         -!message *** Compiler does not have 'Optimizations'
    95         -OPTIMIZING	= 0
    96         -!endif
    97         -
    98         -OPTIMIZATIONS  =
    99         -
   100         -!if [nmakehlp -c -Ot]
   101         -OPTIMIZATIONS  = $(OPTIMIZATIONS) -Ot
   102         -!endif
   103         -
   104         -!if [nmakehlp -c -Oi]
   105         -OPTIMIZATIONS  = $(OPTIMIZATIONS) -Oi
   106         -!endif
   107         -
   108         -!if [nmakehlp -c -Op]
   109         -OPTIMIZATIONS  = $(OPTIMIZATIONS) -Op
   110         -!endif
   111         -
   112         -!if [nmakehlp -c -fp:strict]
   113         -OPTIMIZATIONS  = $(OPTIMIZATIONS) -fp:strict
   114         -!endif
   115         -
   116         -!if [nmakehlp -c -Gs]
   117         -OPTIMIZATIONS  = $(OPTIMIZATIONS) -Gs
   118         -!endif
   119         -
   120         -!if [nmakehlp -c -GS]
   121         -OPTIMIZATIONS  = $(OPTIMIZATIONS) -GS
   122         -!endif
   123         -
   124         -!if [nmakehlp -c -GL]
   125         -OPTIMIZATIONS  = $(OPTIMIZATIONS) -GL
   126         -!endif
   127         -
   128         -DEBUGFLAGS     =
   129         -
   130         -!if [nmakehlp -c -RTC1]
   131         -DEBUGFLAGS     = $(DEBUGFLAGS) -RTC1
   132         -!elseif [nmakehlp -c -GZ]
   133         -DEBUGFLAGS     = $(DEBUGFLAGS) -GZ
   134         -!endif
   135         -
   136         -COMPILERFLAGS  =-W3
   137         -
   138         -# In v13 -GL and -YX are incompatible.
   139         -!if [nmakehlp -c -YX]
   140         -!if ![nmakehlp -c -GL]
   141         -OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
   142         -!endif
   143         -!endif
   144         -
   145         -!if "$(MACHINE)" == "IX86"
   146         -### test for pentium errata
   147         -!if [nmakehlp -c -QI0f]
   148         -!message *** Compiler has 'Pentium 0x0f fix'
   149         -COMPILERFLAGS  = $(COMPILERFLAGSS) -QI0f
   150         -!else
   151         -!message *** Compiler does not have 'Pentium 0x0f fix'
   152         -!endif
   153         -!endif
   154         -
   155         -!if "$(MACHINE)" == "IA64"
   156         -### test for Itanium errata
   157         -!if [nmakehlp -c -QIA64_Bx]
   158         -!message *** Compiler has 'B-stepping errata workarounds'
   159         -COMPILERFLAGS   = $(COMPILERFLAGS) -QIA64_Bx
   160         -!else
   161         -!message *** Compiler does not have 'B-stepping errata workarounds'
   162         -!endif
   163         -!endif
   164         -
   165         -!if "$(MACHINE)" == "IX86"
   166         -### test for -align:4096, when align:512 will do.
   167         -!if [nmakehlp -l -opt:nowin98]
   168         -!message *** Linker has 'Win98 alignment problem'
   169         -ALIGN98_HACK	= 1
   170         -!else
   171         -!message *** Linker does not have 'Win98 alignment problem'
   172         -ALIGN98_HACK	= 0
   173         -!endif
   174         -!else
   175         -ALIGN98_HACK	= 0
   176         -!endif
   177         -
   178         -LINKERFLAGS     =
   179         -
   180         -!if [nmakehlp -l -ltcg]
   181         -LINKERFLAGS     =-ltcg
   182         -!endif
   183         -
   184         -#----------------------------------------------------------
   185         -# MSVC8 (ships with Visual Studio 2005) generates a manifest
   186         -# file that we should link into the binaries. This is how.
   187         -#----------------------------------------------------------
   188         -
          149  +######################################################################
          150  +# 2. Figure out our build environment in terms of what we're building.
          151  +#
          152  +# (a) Tcl itself
          153  +# (b) Tk
          154  +# (c) a Tcl extension using libraries/includes from an *installed* Tcl
          155  +# (d) a Tcl extension using libraries/includes from Tcl source directory
          156  +#
          157  +# This last is needed because some extensions still need
          158  +# some Tcl interfaces that are not publicly exposed.
          159  +#
          160  +# The fragment will set the following macros:
          161  +# ROOT - root of this module sources
          162  +# COMPATDIR - source directory that holds compatibility sources
          163  +# DOCDIR - source directory containing documentation files
          164  +# GENERICDIR - platform-independent source directory
          165  +# WINDIR - Windows-specific source directory
          166  +# TESTDIR - directory containing test files
          167  +# TOOLSDIR - directory containing build tools
          168  +# _TCLDIR - root of the Tcl installation OR the Tcl sources. Not set
          169  +#    when building Tcl itself.
          170  +# _INSTALLDIR - native form of the installation path. For Tcl
          171  +#    this will be the root of the Tcl installation. For extensions
          172  +#    this will be the lib directory under the root.
          173  +# TCLINSTALL  - set to 1 if _TCLDIR refers to
          174  +#    headers and libraries from an installed Tcl, and 0 if built against
          175  +#    Tcl sources. Not set when building Tcl itself. Yes, not very well
          176  +#    named.
          177  +# _TCL_H - native path to the tcl.h file
          178  +#
          179  +# If Tk is involved, also sets the following
          180  +# _TKDIR - native form Tk installation OR Tk source. Not set if building
          181  +#    Tk itself.
          182  +# TKINSTALL - set 1 if _TKDIR refers to installed Tk and 0 if Tk sources
          183  +# _TK_H - native path to the tk.h file
          184  +
          185  +# Root directory for sources and assumed subdirectories
          186  +ROOT = $(MAKEDIR)\..
          187  +# The following paths CANNOT have spaces in them as they appear on the
          188  +# left side of implicit rules.
          189  +!ifndef COMPATDIR
          190  +COMPATDIR	= $(ROOT)\compat
          191  +!endif
          192  +!ifndef DOCDIR
          193  +DOCDIR		= $(ROOT)\doc
          194  +!endif
          195  +!ifndef GENERICDIR
          196  +GENERICDIR	= $(ROOT)\generic
          197  +!endif
          198  +!ifndef TOOLSDIR
          199  +TOOLSDIR	= $(ROOT)\tools
          200  +!endif
          201  +!ifndef TESTDIR
          202  +TESTDIR	= $(ROOT)\tests
          203  +!endif
          204  +!ifndef LIBDIR
          205  +!if exist("$(ROOT)\library")
          206  +LIBDIR          = $(ROOT)\library
          207  +!else
          208  +LIBDIR          = $(ROOT)\lib
          209  +!endif
          210  +!endif
          211  +!ifndef DEMODIR
          212  +!if exist("$(LIBDIR)\demos")
          213  +DEMODIR		= $(LIBDIR)\demos
          214  +!else
          215  +DEMODIR		= $(ROOT)\demos
          216  +!endif
          217  +!endif # ifndef DEMODIR
          218  +# Do NOT enclose WINDIR in a !ifndef because Windows always defines
          219  +# WINDIR env var to point to c:\windows!
          220  +# TBD - This is a potentially dangerous conflict, rename WINDIR to
          221  +# something else
          222  +WINDIR		= $(ROOT)\win
          223  +
          224  +!ifndef RCDIR
          225  +!if exist("$(WINDIR)\rc")
          226  +RCDIR           = $(WINDIR)\rc
          227  +!else
          228  +RCDIR           = $(WINDIR)
          229  +!endif
          230  +!endif
          231  +RCDIR = $(RCDIR:/=\)
          232  +
          233  +# The target directory where the built packages and binaries will be installed.
          234  +# INSTALLDIR is the (optional) path specified by the user.
          235  +# _INSTALLDIR is INSTALLDIR using the backslash separator syntax
          236  +!ifdef INSTALLDIR
          237  +### Fix the path separators.
          238  +_INSTALLDIR	= $(INSTALLDIR:/=\)
          239  +!else
          240  +### Assume the normal default.
          241  +_INSTALLDIR	= $(HOMEDRIVE)\Tcl
          242  +!endif
          243  +
          244  +!if $(DOING_TCL)
          245  +
          246  +# BEGIN Case 2(a) - Building Tcl itself
          247  +
          248  +# Only need to define _TCL_H
          249  +_TCL_H = ..\generic\tcl.h
          250  +
          251  +# END Case 2(a) - Building Tcl itself
          252  +
          253  +!elseif $(DOING_TK)
          254  +
          255  +# BEGIN Case 2(b) - Building Tk
          256  +
          257  +TCLINSTALL = 0 # Tk always builds against Tcl source, not an installed Tcl
          258  +!if "$(TCLDIR)" == ""
          259  +!if [echo TCLDIR = \> nmakehlp.out] \
          260  +   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
          261  +!error *** Could not locate Tcl source directory.
          262  +!endif
          263  +!include nmakehlp.out
          264  +!endif # TCLDIR == ""
          265  +
          266  +_TCLDIR	= $(TCLDIR:/=\)
          267  +_TCL_H  = $(_TCLDIR)\generic\tcl.h
          268  +!if !exist("$(_TCL_H)")
          269  +!error Could not locate tcl.h. Please set the TCLDIR macro to point to the Tcl *source* directory.
          270  +!endif
          271  +
          272  +_TK_H = ..\generic\tk.h
          273  +
          274  +# END Case 2(b) - Building Tk
          275  +
          276  +!else
          277  +
          278  +# BEGIN Case 2(c) or (d) - Building an extension other than Tk
          279  +
          280  +# If command line has specified Tcl location through TCLDIR, use it
          281  +# else default to the INSTALLDIR setting
          282  +!if "$(TCLDIR)" != ""
          283  +
          284  +_TCLDIR	= $(TCLDIR:/=\)
          285  +!if exist("$(_TCLDIR)\include\tcl.h") # Case 2(c) with TCLDIR defined
          286  +TCLINSTALL	= 1
          287  +_TCL_H          = $(_TCLDIR)\include\tcl.h
          288  +!elseif exist("$(_TCLDIR)\generic\tcl.h") # Case 2(d) with TCLDIR defined
          289  +TCLINSTALL	= 0
          290  +_TCL_H          = $(_TCLDIR)\generic\tcl.h
          291  +!endif
          292  +
          293  +!else  #  # Case 2(c) for extensions with TCLDIR undefined
          294  +
          295  +# Need to locate Tcl depending on whether it needs Tcl source or not.
          296  +# If we don't, check the INSTALLDIR for an installed Tcl first
          297  +
          298  +!if exist("$(_INSTALLDIR)\include\tcl.h") && !$(NEED_TCL_SOURCE)
          299  +
          300  +TCLINSTALL	= 1
          301  +TCLDIR          = $(_INSTALLDIR)\..
          302  +# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
          303  +# later so the \.. accounts for the /lib
          304  +_TCLDIR		= $(_INSTALLDIR)\..
          305  +_TCL_H          = $(_TCLDIR)\include\tcl.h
          306  +
          307  +!else # exist(...) && ! $(NEED_TCL_SOURCE)
          308  +
          309  +!if [echo _TCLDIR = \> nmakehlp.out] \
          310  +   || [nmakehlp -L generic\tcl.h >> nmakehlp.out]
          311  +!error *** Could not locate Tcl source directory.
          312  +!endif
          313  +!include nmakehlp.out
          314  +TCLINSTALL      = 0
          315  +TCLDIR         = $(_TCLDIR)
          316  +_TCL_H          = $(_TCLDIR)\generic\tcl.h
          317  +
          318  +!endif # exist(...) && ! $(NEED_TCL_SOURCE)
          319  +
          320  +!endif # TCLDIR
          321  +
          322  +!ifndef _TCL_H
          323  +MSG =^
          324  +Failed to find tcl.h. The TCLDIR macro is set incorrectly or is not set and default path does not contain tcl.h.
          325  +!error $(MSG)
          326  +!endif
          327  +
          328  +# Now do the same to locate Tk headers and libs if project requires Tk
          329  +!if $(NEED_TK)
          330  +
          331  +!if "$(TKDIR)" != ""
          332  +
          333  +_TKDIR = $(TKDIR:/=\)
          334  +!if exist("$(_TKDIR)\include\tk.h")
          335  +TKINSTALL      = 1
          336  +_TK_H          = $(_TKDIR)\include\tk.h
          337  +!elseif exist("$(_TKDIR)\generic\tk.h")
          338  +TKINSTALL      = 0
          339  +_TK_H          = $(_TKDIR)\generic\tk.h
          340  +!endif
          341  +
          342  +!else # TKDIR not defined
          343  +
          344  +# Need to locate Tcl depending on whether it needs Tcl source or not.
          345  +# If we don't, check the INSTALLDIR for an installed Tcl first
          346  +
          347  +!if exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
          348  +
          349  +TKINSTALL      = 1
          350  +# NOTE: we will be resetting _INSTALLDIR to _INSTALLDIR/lib for extensions
          351  +# later so the \.. accounts for the /lib
          352  +_TKDIR         = $(_INSTALLDIR)\..
          353  +_TK_H          = $(_TKDIR)\include\tk.h
          354  +TKDIR          = $(_TKDIR)
          355  +
          356  +!else # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
          357  +
          358  +!if [echo _TKDIR = \> nmakehlp.out] \
          359  +   || [nmakehlp -L generic\tk.h >> nmakehlp.out]
          360  +!error *** Could not locate Tk source directory.
          361  +!endif
          362  +!include nmakehlp.out
          363  +TKINSTALL      = 0
          364  +TKDIR          = $(_TKDIR)
          365  +_TK_H          = $(_TKDIR)\generic\tk.h
          366  +
          367  +!endif # exist("$(_INSTALLDIR)\include\tk.h") && !$(NEED_TK_SOURCE)
          368  +
          369  +!endif # TKDIR
          370  +
          371  +!ifndef _TK_H
          372  +MSG =^
          373  +Failed to find tk.h. The TKDIR macro is set incorrectly or is not set and default path does not contain tk.h.
          374  +!error $(MSG)
          375  +!endif
          376  +
          377  +!endif # NEED_TK
          378  +
          379  +!if $(NEED_TCL_SOURCE) && $(TCLINSTALL)
          380  +MSG = ^
          381  +*** Warning: This extension requires the source distribution of Tcl.^
          382  +*** Please set the TCLDIR macro to point to the Tcl sources.
          383  +!error $(MSG)
          384  +!endif
          385  +
          386  +!if $(NEED_TK_SOURCE)
          387  +!if $(TKINSTALL)
          388  +MSG = ^
          389  +*** Warning: This extension requires the source distribution of Tk.^
          390  +*** Please set the TKDIR macro to point to the Tk sources.
          391  +!error $(MSG)
          392  +!endif
          393  +!endif
          394  +
          395  +
          396  +# If INSTALLDIR set to tcl installation root dir then reset to the
          397  +# lib dir for installing extensions 
          398  +!if exist("$(_INSTALLDIR)\include\tcl.h")
          399  +_INSTALLDIR=$(_INSTALLDIR)\lib
          400  +!endif
          401  +
          402  +# END Case 2(c) or (d) - Building an extension
          403  +!endif # if $(DOING_TCL)
          404  +
          405  +################################################################
          406  +# 3. Determine compiler version and architecture
          407  +# In this section, we figure out the compiler version and the
          408  +# architecture for which we are building. This sets the
          409  +# following macros:
          410  +# VCVERSION - the internal compiler version as 1200, 1400, 1910 etc.
          411  +#     This is also printed by the compiler in dotted form 19.10 etc.
          412  +# VCVER - the "marketing version", for example Visual C++ 6 for internal
          413  +#     compiler version 1200. This is kept only for legacy reasons as it
          414  +#     does not make sense for recent Microsoft compilers. Only used for
          415  +#     output directory names.
          416  +# ARCH - set to IX86 or AMD64 depending on 32- or 64-bit target
          417  +# NATIVE_ARCH - set to IX86 or AMD64 for the host machine
          418  +# MACHINE - same as $(ARCH) - legacy
          419  +# _VC_MANIFEST_EMBED_{DLL,EXE} - commands for embedding a manifest if needed
          420  +# CFG_ENCODING - set to an character encoding.
          421  +#   TBD - this is passed to compiler as TCL_CFGVAL_ENCODING but can't
          422  +#   see where it is used
          423  +
          424  +cc32		= $(CC)   # built-in default.
          425  +link32		= link
          426  +lib32		= lib
          427  +rc32		= $(RC)   # built-in default.
          428  +
          429  +#----------------------------------------------------------------
          430  +# Figure out the compiler architecture and version by writing
          431  +# the C macros to a file, preprocessing them with the C
          432  +# preprocessor and reading back the created file
          433  +
          434  +_HASH=^#
   189    435   _VC_MANIFEST_EMBED_EXE=
   190    436   _VC_MANIFEST_EMBED_DLL=
   191    437   VCVER=0
   192    438   !if ![echo VCVERSION=_MSC_VER > vercl.x] \
   193         -    && ![cl -nologo -TC -P vercl.x $(ERRNULL)]
          439  +    && ![echo $(_HASH)if defined(_M_IX86) >> vercl.x] \
          440  +    && ![echo ARCH=IX86 >> vercl.x] \
          441  +    && ![echo $(_HASH)elif defined(_M_AMD64) >> vercl.x] \
          442  +    && ![echo ARCH=AMD64 >> vercl.x] \
          443  +    && ![echo $(_HASH)endif >> vercl.x] \
          444  +    && ![$(cc32) -nologo -TC -P vercl.x 2>NUL]
   194    445   !include vercl.i
   195         -!if $(VCVERSION) >= 1500
   196         -VCVER=9
   197         -!elseif $(VCVERSION) >= 1400
   198         -VCVER=8
   199         -!elseif $(VCVERSION) >= 1300
   200         -VCVER=7
   201         -!elseif $(VCVERSION) >= 1200
   202         -VCVER=6
          446  +!if $(VCVERSION) < 1900
          447  +!if ![echo VCVER= ^\> vercl.vc] \
          448  +    && ![set /a $(VCVERSION) / 100 - 6 >> vercl.vc]
          449  +!include vercl.vc
   203    450   !endif
          451  +!else
          452  +# The simple calculation above does not apply to new Visual Studio releases
          453  +# Keep the compiler version in its native form.
          454  +VCVER = $(VCVERSION)
          455  +!endif
          456  +!endif
          457  +
          458  +!if ![del 2>NUL /q/f vercl.x vercl.i vercl.vc]
          459  +!endif
          460  +
          461  +#----------------------------------------------------------------
          462  +# The MACHINE macro is used by legacy makefiles so set it as well
          463  +!ifdef MACHINE
          464  +!if "$(MACHINE)" == "x86"
          465  +!undef MACHINE
          466  +MACHINE = IX86
          467  +!elseif "$(MACHINE)" == "x64"
          468  +!undef MACHINE
          469  +MACHINE = AMD64
          470  +!endif
          471  +!if "$(MACHINE)" != "$(ARCH)"
          472  +!error Specified MACHINE macro $(MACHINE) does not match detected target architecture $(ARCH).
          473  +!endif
          474  +!else
          475  +MACHINE=$(ARCH)
          476  +!endif
          477  +
          478  +#------------------------------------------------------------
          479  +# Figure out the *host* architecture by reading the registry
          480  +
          481  +!if ![reg query HKLM\Hardware\Description\System\CentralProcessor\0 /v Identifier | findstr /i x86]
          482  +NATIVE_ARCH=IX86
          483  +!else
          484  +NATIVE_ARCH=AMD64
   204    485   !endif
   205    486   
   206    487   # Since MSVC8 we must deal with manifest resources.
   207    488   !if $(VCVERSION) >= 1400
   208    489   _VC_MANIFEST_EMBED_EXE=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;1
   209    490   _VC_MANIFEST_EMBED_DLL=if exist $@.manifest mt -nologo -manifest $@.manifest -outputresource:$@;2
   210    491   !endif
   211    492   
   212         -#----------------------------------------------------------
   213         -# Decode the options requested.
   214         -#----------------------------------------------------------
   215         -
   216         -!if "$(OPTS)" == "" || [nmakehlp -f "$(OPTS)" "none"]
          493  +!ifndef CFG_ENCODING
          494  +CFG_ENCODING	= \"cp1252\"
          495  +!endif
          496  +
          497  +################################################################
          498  +# 4. Build the nmakehlp program
          499  +# This is a helper app we need to overcome nmake's limiting
          500  +# environment. We will call out to it to get various bits of
          501  +# information about supported compiler options etc.
          502  +#
          503  +# Tcl itself will always use the nmakehlp.c program which is
          504  +# in its own source. This is the "master" copy and kept updated.
          505  +#
          506  +# Extensions built against an installed Tcl will use the installed
          507  +# copy of Tcl's nmakehlp.c if there is one and their own version
          508  +# otherwise. In the latter case, they would also be using their own
          509  +# rules.vc. Note that older versions of Tcl do not install nmakehlp.c
          510  +# or rules.vc.
          511  +#
          512  +# Extensions built against Tcl sources will use the one from the Tcl source.
          513  +#
          514  +# When building an extension using a sufficiently new version of Tcl,
          515  +# rules-ext.vc will define NMAKEHLPC appropriately to point to the
          516  +# copy of nmakehlp.c to be used.
          517  +
          518  +!ifndef NMAKEHLPC
          519  +# Default to the one in the current directory (the extension's own nmakehlp.c)
          520  +NMAKEHLPC = nmakehlp.c
          521  +
          522  +!if !$(DOING_TCL)
          523  +!if $(TCLINSTALL)
          524  +!if exist("$(_TCLDIR)\lib\nmake\nmakehlp.c")
          525  +NMAKEHLPC = $(_TCLDIR)\lib\nmake\nmakehlp.c
          526  +!endif
          527  +!else # ! $(TCLINSTALL)
          528  +!if exist("$(_TCLDIR)\win\nmakehlp.c")
          529  +NMAKEHLPC = $(_TCLDIR)\win\nmakehlp.c
          530  +!endif
          531  +!endif # $(TCLINSTALL)
          532  +!endif # !$(DOING_TCL)
          533  +
          534  +!endif # NMAKEHLPC
          535  +
          536  +# We always build nmakehlp even if it exists since we do not know
          537  +# what source it was built from.
          538  +!if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul]
          539  +!endif
          540  +
          541  +################################################################
          542  +# 5. Test for compiler features
          543  +# Visual C++ compiler options have changed over the years. Check
          544  +# which options are supported by the compiler in use.
          545  +#
          546  +# The following macros are set:
          547  +# OPTIMIZATIONS - the compiler flags to be used for optimized builds
          548  +# DEBUGFLAGS - the compiler flags to be used for debug builds
          549  +# LINKERFLAGS - Flags passed to the linker 
          550  +#
          551  +# Note that these are the compiler settings *available*, not those
          552  +# that will be *used*. The latter depends on the OPTS macro settings
          553  +# which we have not yet parsed.
          554  +#
          555  +# Also note that some of the flags in OPTIMIZATIONS are not really
          556  +# related to optimization. They are placed there only for legacy reasons
          557  +# as some extensions expect them to be included in that macro.
          558  +
          559  +# -Op improves float consistency. Note only needed for older compilers
          560  +# Newer compilers do not need or support this option.
          561  +!if [nmakehlp -c -Op]
          562  +FPOPTS  = -Op
          563  +!endif
          564  +
          565  +# Strict floating point semantics - present in newer compilers in lieu of -Op
          566  +!if [nmakehlp -c -fp:strict]
          567  +FPOPTS  = $(FPOPTS) -fp:strict
          568  +!endif
          569  +
          570  +!if "$(MACHINE)" == "IX86"
          571  +### test for pentium errata
          572  +!if [nmakehlp -c -QI0f]
          573  +!message *** Compiler has 'Pentium 0x0f fix'
          574  +FPOPTS  = $(FPOPTS) -QI0f
          575  +!else
          576  +!message *** Compiler does not have 'Pentium 0x0f fix'
          577  +!endif
          578  +!endif
          579  +
          580  +### test for optimizations
          581  +# /O2 optimization includes /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy as per
          582  +# documentation. Note we do NOT want /Gs as that inserts a _chkstk
          583  +# stack probe at *every* function entry, not just those with more than
          584  +# a page of stack allocation resulting in a performance hit.  However,
          585  +# /O2 documentation is misleading as its stack probes are simply the
          586  +# default page size locals allocation probes and not what is implied
          587  +# by an explicit /Gs option.
          588  +
          589  +OPTIMIZATIONS = $(FPOPTS)
          590  +
          591  +!if [nmakehlp -c -O2]
          592  +OPTIMIZING = 1
          593  +OPTIMIZATIONS   = $(OPTIMIZATIONS) -O2
          594  +!else
          595  +# Legacy, really. All modern compilers support this
          596  +!message *** Compiler does not have 'Optimizations'
          597  +OPTIMIZING = 0
          598  +!endif
          599  +
          600  +# Checks for buffer overflows in local arrays
          601  +!if [nmakehlp -c -GS]
          602  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -GS
          603  +!endif
          604  +
          605  +# Link time optimization. Note that this option (potentially) makes
          606  +# generated libraries only usable by the specific VC++ version that
          607  +# created it. Requires /LTCG linker option
          608  +!if [nmakehlp -c -GL]
          609  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -GL
          610  +CC_GL_OPT_ENABLED = 1
          611  +!else
          612  +# In newer compilers -GL and -YX are incompatible.
          613  +!if [nmakehlp -c -YX]
          614  +OPTIMIZATIONS  = $(OPTIMIZATIONS) -YX
          615  +!endif
          616  +!endif # [nmakehlp -c -GL]
          617  +
          618  +DEBUGFLAGS     = $(FPOPTS)
          619  +
          620  +# Run time error checks. Not available or valid in a release, non-debug build
          621  +# RTC is for modern compilers, -GZ is legacy
          622  +!if [nmakehlp -c -RTC1]
          623  +DEBUGFLAGS     = $(DEBUGFLAGS) -RTC1
          624  +!elseif [nmakehlp -c -GZ]
          625  +DEBUGFLAGS     = $(DEBUGFLAGS) -GZ
          626  +!endif
          627  +
          628  +#----------------------------------------------------------------
          629  +# Linker flags
          630  +
          631  +# LINKER_TESTFLAGS are for internal use when we call nmakehlp to test
          632  +# if the linker supports a specific option. Without these flags link will
          633  +# return "LNK1561: entry point must be defined" error compiling from VS-IDE:
          634  +# They are not passed through to the actual application / extension
          635  +# link rules.
          636  +!ifndef LINKER_TESTFLAGS
          637  +LINKER_TESTFLAGS = /DLL /NOENTRY /OUT:nmakehlp.out
          638  +!endif
          639  +
          640  +LINKERFLAGS     =
          641  +
          642  +# If compiler has enabled link time optimization, linker must too with -ltcg
          643  +!ifdef CC_GL_OPT_ENABLED
          644  +!if [nmakehlp -l -ltcg $(LINKER_TESTFLAGS)]
          645  +LINKERFLAGS     = $(LINKERFLAGS) -ltcg
          646  +!endif
          647  +!endif
          648  +
          649  +########################################################################
          650  +# 6. Parse the OPTS macro to work out the requested build configuration.
          651  +# Based on this, we will construct the actual switches to be passed to the
          652  +# compiler and linker using the macros defined in the previous section.
          653  +# The following macros are defined by this section based on OPTS
          654  +# STATIC_BUILD - 0 -> Tcl is to be built as a shared library
          655  +#                1 -> build as a static library and shell
          656  +# TCL_THREADS - legacy but always 1 on Windows since winsock requires it.
          657  +# DEBUG - 1 -> debug build, 0 -> release builds
          658  +# SYMBOLS - 1 -> generate PDB's, 0 -> no PDB's
          659  +# PROFILE - 1 -> generate profiling info, 0 -> no profiling
          660  +# PGO     - 1 -> profile based optimization, 0 -> no
          661  +# MSVCRT  - 1 -> link to dynamic C runtime even when building static Tcl build
          662  +#           0 -> link to static C runtime for static Tcl build.
          663  +#           Does not impact shared Tcl builds (STATIC_BUILD == 0)
          664  +# TCL_USE_STATIC_PACKAGES - 1 -> statically link the registry and dde extensions
          665  +#           in the Tcl shell. 0 -> keep them as shared libraries
          666  +#           Does not impact shared Tcl builds.
          667  +# USE_THREAD_ALLOC - 1 -> Use a shared global free pool for allocation.
          668  +#           0 -> Use the non-thread allocator.
          669  +# UNCHECKED - 1 -> when doing a debug build with symbols, use the release
          670  +#           C runtime, 0 -> use the debug C runtime.
          671  +# USE_STUBS - 1 -> compile to use stubs interfaces, 0 -> direct linking
          672  +# CONFIG_CHECK - 1 -> check current build configuration against Tcl
          673  +#           configuration (ignored for Tcl itself)
          674  +# Further, LINKERFLAGS are modified based on above.
          675  +
          676  +# Default values for all the above
   217    677   STATIC_BUILD	= 0
   218    678   TCL_THREADS	= 1
   219    679   DEBUG		= 0
          680  +SYMBOLS		= 0
   220    681   PROFILE		= 0
   221         -MSVCRT		= 0
   222         -LOIMPACT	= 0
          682  +PGO		= 0
          683  +MSVCRT		= 1
   223    684   TCL_USE_STATIC_PACKAGES	= 0
   224    685   USE_THREAD_ALLOC = 1
   225         -USE_THREAD_STORAGE = 1
   226         -UNCHECKED       = 0
          686  +UNCHECKED	= 0
          687  +CONFIG_CHECK    = 1
          688  +!if $(DOING_TCL)
          689  +USE_STUBS       = 0
   227    690   !else
          691  +USE_STUBS       = 1
          692  +!endif
          693  +
          694  +# If OPTS is not empty AND does not contain "none" which turns off all OPTS
          695  +# set the above macros based on OPTS content
          696  +!if "$(OPTS)" != "" && ![nmakehlp -f "$(OPTS)" "none"]
          697  +
          698  +# OPTS are specified, parse them
          699  +
   228    700   !if [nmakehlp -f $(OPTS) "static"]
   229    701   !message *** Doing static
   230    702   STATIC_BUILD	= 1
          703  +!endif
          704  +
          705  +!if [nmakehlp -f $(OPTS) "nostubs"]
          706  +!message *** Not using stubs
          707  +USE_STUBS	= 0
          708  +!endif
          709  +
          710  +!if [nmakehlp -f $(OPTS) "nomsvcrt"]
          711  +!message *** Doing nomsvcrt
          712  +MSVCRT		= 0
   231    713   !else
   232         -STATIC_BUILD	= 0
   233         -!endif
   234    714   !if [nmakehlp -f $(OPTS) "msvcrt"]
   235    715   !message *** Doing msvcrt
   236    716   MSVCRT		= 1
   237    717   !else
          718  +!if !$(STATIC_BUILD)
          719  +MSVCRT		= 1
          720  +!else
   238    721   MSVCRT		= 0
   239    722   !endif
   240         -!if [nmakehlp -f $(OPTS) "staticpkg"]
          723  +!endif
          724  +!endif # [nmakehlp -f $(OPTS) "nomsvcrt"]
          725  +
          726  +!if [nmakehlp -f $(OPTS) "staticpkg"] && $(STATIC_BUILD)
   241    727   !message *** Doing staticpkg
   242    728   TCL_USE_STATIC_PACKAGES	= 1
   243    729   !else
   244    730   TCL_USE_STATIC_PACKAGES	= 0
   245    731   !endif
          732  +
   246    733   !if [nmakehlp -f $(OPTS) "nothreads"]
   247    734   !message *** Compile explicitly for non-threaded tcl
   248    735   TCL_THREADS	= 0
          736  +USE_THREAD_ALLOC= 0
   249    737   !else
   250         -TCL_THREADS     = 1
          738  +TCL_THREADS	= 1
          739  +USE_THREAD_ALLOC= 1
   251    740   !endif
          741  +
   252    742   !if [nmakehlp -f $(OPTS) "symbols"]
   253    743   !message *** Doing symbols
   254    744   DEBUG		= 1
   255    745   !else
   256    746   DEBUG		= 0
   257    747   !endif
          748  +
          749  +!if [nmakehlp -f $(OPTS) "pdbs"]
          750  +!message *** Doing pdbs
          751  +SYMBOLS		= 1
          752  +!else
          753  +SYMBOLS		= 0
          754  +!endif
          755  +
   258    756   !if [nmakehlp -f $(OPTS) "profile"]
   259    757   !message *** Doing profile
   260    758   PROFILE		= 1
   261    759   !else
   262    760   PROFILE		= 0
   263    761   !endif
          762  +
          763  +!if [nmakehlp -f $(OPTS) "pgi"]
          764  +!message *** Doing profile guided optimization instrumentation
          765  +PGO		= 1
          766  +!elseif [nmakehlp -f $(OPTS) "pgo"]
          767  +!message *** Doing profile guided optimization
          768  +PGO		= 2
          769  +!else
          770  +PGO		= 0
          771  +!endif
          772  +
   264    773   !if [nmakehlp -f $(OPTS) "loimpact"]
   265         -!message *** Doing loimpact
   266         -LOIMPACT	= 1
   267         -!else
   268         -LOIMPACT	= 0
          774  +!message *** Warning: ignoring option "loimpact" - deprecated on modern Windows.
   269    775   !endif
          776  +
          777  +# TBD - should get rid of this option
   270    778   !if [nmakehlp -f $(OPTS) "thrdalloc"]
   271    779   !message *** Doing thrdalloc
   272    780   USE_THREAD_ALLOC = 1
   273         -!else
          781  +!endif
          782  +
          783  +!if [nmakehlp -f $(OPTS) "tclalloc"]
   274    784   USE_THREAD_ALLOC = 0
   275    785   !endif
   276         -!if [nmakehlp -f $(OPTS) "thrdstorage"]
   277         -!message *** Doing thrdstorage
   278         -USE_THREAD_STORAGE = 1
   279         -!else
   280         -USE_THREAD_STORAGE = 0
   281         -!endif
          786  +
   282    787   !if [nmakehlp -f $(OPTS) "unchecked"]
   283    788   !message *** Doing unchecked
   284    789   UNCHECKED = 1
   285    790   !else
   286    791   UNCHECKED = 0
   287    792   !endif
   288         -!endif
   289         -
   290         -
   291         -!if !$(STATIC_BUILD)
   292         -# Make sure we don't build overly fat DLLs.
   293         -MSVCRT		= 1
   294         -# We shouldn't statically put the extensions inside the shell when dynamic.
   295         -TCL_USE_STATIC_PACKAGES = 0
   296         -!endif
   297         -
   298         -
   299         -#----------------------------------------------------------
          793  +
          794  +!if [nmakehlp -f $(OPTS) "noconfigcheck"]
          795  +CONFIG_CHECK = 1
          796  +!else
          797  +CONFIG_CHECK = 0
          798  +!endif
          799  +
          800  +!endif # "$(OPTS)" != ""  && ... parsing of OPTS
          801  +
          802  +# Set linker flags based on above
          803  +
          804  +!if $(PGO) > 1
          805  +!if [nmakehlp -l -ltcg:pgoptimize $(LINKER_TESTFLAGS)]
          806  +LINKERFLAGS	= $(LINKERFLAGS:-ltcg=) -ltcg:pgoptimize
          807  +!else
          808  +MSG=^
          809  +This compiler does not support profile guided optimization.
          810  +!error $(MSG)
          811  +!endif
          812  +!elseif $(PGO) > 0
          813  +!if [nmakehlp -l -ltcg:pginstrument $(LINKER_TESTFLAGS)]
          814  +LINKERFLAGS	= $(LINKERFLAGS:-ltcg=) -ltcg:pginstrument
          815  +!else
          816  +MSG=^
          817  +This compiler does not support profile guided optimization.
          818  +!error $(MSG)
          819  +!endif
          820  +!endif
          821  +
          822  +################################################################
          823  +# 7. Parse the STATS macro to configure code instrumentation
          824  +# The following macros are set by this section:
          825  +# TCL_MEM_DEBUG - 1 -> enables memory allocation instrumentation
          826  +#                 0 -> disables
          827  +# TCL_COMPILE_DEBUG - 1 -> enables byte compiler logging
          828  +#                     0 -> disables
          829  +
          830  +# Default both are off
          831  +TCL_MEM_DEBUG	    = 0
          832  +TCL_COMPILE_DEBUG   = 0
          833  +
          834  +!if "$(STATS)" != "" && ![nmakehlp -f "$(STATS)" "none"]
          835  +
          836  +!if [nmakehlp -f $(STATS) "memdbg"]
          837  +!message *** Doing memdbg
          838  +TCL_MEM_DEBUG	    = 1
          839  +!else
          840  +TCL_MEM_DEBUG	    = 0
          841  +!endif
          842  +
          843  +!if [nmakehlp -f $(STATS) "compdbg"]
          844  +!message *** Doing compdbg
          845  +TCL_COMPILE_DEBUG   = 1
          846  +!else
          847  +TCL_COMPILE_DEBUG   = 0
          848  +!endif
          849  +
          850  +!endif
          851  +
          852  +####################################################################
          853  +# 8. Parse the CHECKS macro to configure additional compiler checks
          854  +# The following macros are set by this section:
          855  +# WARNINGS - compiler switches that control the warnings level
          856  +# TCL_NO_DEPRECATED - 1 -> disable support for deprecated functions
          857  +#                     0 -> enable deprecated functions
          858  +
          859  +# Defaults - Permit deprecated functions and warning level 3
          860  +TCL_NO_DEPRECATED	    = 0
          861  +WARNINGS		    = -W3
          862  +
          863  +!if "$(CHECKS)" != "" && ![nmakehlp -f "$(CHECKS)" "none"]
          864  +
          865  +!if [nmakehlp -f $(CHECKS) "nodep"]
          866  +!message *** Doing nodep check
          867  +TCL_NO_DEPRECATED	    = 1
          868  +!endif
          869  +
          870  +!if [nmakehlp -f $(CHECKS) "fullwarn"]
          871  +!message *** Doing full warnings check
          872  +WARNINGS		    = -W4
          873  +!if [nmakehlp -l -warn:3 $(LINKER_TESTFLAGS)]
          874  +LINKERFLAGS		    = $(LINKERFLAGS) -warn:3
          875  +!endif
          876  +!endif
          877  +
          878  +!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
          879  +!message *** Doing 64bit portability warnings
          880  +WARNINGS		    = $(WARNINGS) -Wp64
          881  +!endif
          882  +
          883  +!endif
          884  +
          885  +################################################################
          886  +# 9. Extract various version numbers
          887  +# For Tcl and Tk, version numbers are extracted from tcl.h and tk.h
          888  +# respectively. For extensions, versions are extracted from the
          889  +# configure.in or configure.ac from the TEA configuration if it
          890  +# exists, and unset otherwise.
          891  +# Sets the following macros:
          892  +# TCL_MAJOR_VERSION
          893  +# TCL_MINOR_VERSION
          894  +# TCL_PATCH_LEVEL
          895  +# TCL_VERSION
          896  +# TK_MAJOR_VERSION
          897  +# TK_MINOR_VERSION
          898  +# TK_PATCH_LEVEL
          899  +# TK_VERSION
          900  +# DOTVERSION - set as (for example) 2.5
          901  +# VERSION - set as (for example 25)
          902  +#--------------------------------------------------------------
          903  +
          904  +!if [echo REM = This file is generated from rules.vc > versions.vc]
          905  +!endif
          906  +!if [echo TCL_MAJOR_VERSION = \>> versions.vc] \
          907  +   && [nmakehlp -V "$(_TCL_H)" TCL_MAJOR_VERSION >> versions.vc]
          908  +!endif
          909  +!if [echo TCL_MINOR_VERSION = \>> versions.vc] \
          910  +   && [nmakehlp -V "$(_TCL_H)" TCL_MINOR_VERSION >> versions.vc]
          911  +!endif
          912  +!if [echo TCL_PATCH_LEVEL = \>> versions.vc] \
          913  +   && [nmakehlp -V "$(_TCL_H)" TCL_PATCH_LEVEL >> versions.vc]
          914  +!endif
          915  +
          916  +!if defined(_TK_H)
          917  +!if [echo TK_MAJOR_VERSION = \>> versions.vc] \
          918  +   && [nmakehlp -V $(_TK_H) TK_MAJOR_VERSION >> versions.vc]
          919  +!endif
          920  +!if [echo TK_MINOR_VERSION = \>> versions.vc] \
          921  +   && [nmakehlp -V $(_TK_H) TK_MINOR_VERSION >> versions.vc]
          922  +!endif
          923  +!if [echo TK_PATCH_LEVEL = \>> versions.vc] \
          924  +   && [nmakehlp -V $(_TK_H) TK_PATCH_LEVEL >> versions.vc]
          925  +!endif
          926  +!endif # _TK_H
          927  +
          928  +!include versions.vc
          929  +
          930  +TCL_VERSION	= $(TCL_MAJOR_VERSION)$(TCL_MINOR_VERSION)
          931  +TCL_DOTVERSION	= $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
          932  +!if defined(_TK_H)
          933  +TK_VERSION	= $(TK_MAJOR_VERSION)$(TK_MINOR_VERSION)
          934  +TK_DOTVERSION	= $(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
          935  +!endif
          936  +
          937  +# Set DOTVERSION and VERSION
          938  +!if $(DOING_TCL)
          939  +
          940  +DOTVERSION = $(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
          941  +VERSION = $(TCL_VERSION)
          942  +
          943  +!elseif $(DOING_TK)
          944  +
          945  +DOTVERSION = $(TK_DOTVERSION)
          946  +VERSION = $(TK_VERSION)
          947  +
          948  +!else # Doing a non-Tk extension
          949  +
          950  +# If parent makefile has not defined DOTVERSION, try to get it from TEA
          951  +# first from a configure.in file, and then from configure.ac
          952  +!ifndef DOTVERSION
          953  +!if [echo DOTVERSION = \> versions.vc] \
          954  +   || [nmakehlp -V $(ROOT)\configure.in ^[$(PROJECT)^] >> versions.vc]
          955  +!if [echo DOTVERSION = \> versions.vc] \
          956  +   || [nmakehlp -V $(ROOT)\configure.ac ^[$(PROJECT)^] >> versions.vc]
          957  +!error *** Could not figure out extension version. Please define DOTVERSION in parent makefile before including rules.vc.
          958  +!endif
          959  +!endif
          960  +!include versions.vc
          961  +!endif # DOTVERSION
          962  +VERSION         = $(DOTVERSION:.=)
          963  +
          964  +!endif # $(DOING_TCL) ... etc.
          965  +
          966  +################################################################
          967  +# 10. Construct output directory and file paths
   300    968   # Figure-out how to name our intermediate and output directories.
   301         -# We wouldn't want different builds to use the same .obj files
   302         -# by accident.
   303         -#----------------------------------------------------------
   304         -
   305         -#----------------------------------------
   306         -# Naming convention:
          969  +# In order to avoid inadvertent mixing of object files built using
          970  +# different compilers, build configurations etc.,
          971  +#
          972  +# Naming convention (suffixes):
   307    973   #   t = full thread support.
   308         -#   s = static library (as opposed to an
   309         -#	import library)
   310         -#   g = linked to the debug enabled C
   311         -#	run-time.
   312         -#   x = special static build when it
   313         -#	links to the dynamic C run-time.
   314         -#----------------------------------------
   315         -SUFX	    = sgx
          974  +#   s = static library (as opposed to an import library)
          975  +#   g = linked to the debug enabled C run-time.
          976  +#   x = special static build when it links to the dynamic C run-time.
          977  +#
          978  +# The following macros are set in this section:
          979  +# SUFX - the suffix to use for binaries based on above naming convention
          980  +# BUILDDIRTOP - the toplevel default output directory
          981  +#      is of the form {Release,Debug}[_AMD64][_COMPILERVERSION]
          982  +# TMP_DIR - directory where object files are created
          983  +# OUT_DIR - directory where output executables are created
          984  +# Both TMP_DIR and OUT_DIR are defaulted only if not defined by the
          985  +# parent makefile (or command line). The default values are
          986  +# based on BUILDDIRTOP.
          987  +# STUBPREFIX - name of the stubs library for this project
          988  +# PRJIMPLIB - output path of the generated project import library
          989  +# PRJLIBNAME - name of generated project library
          990  +# PRJLIB     - output path of generated project library
          991  +# PRJSTUBLIBNAME - name of the generated project stubs library
          992  +# PRJSTUBLIB - output path of the generated project stubs library
          993  +# RESFILE - output resource file (only if not static build)
          994  +
          995  +SUFX	    = tsgx
   316    996   
   317    997   !if $(DEBUG)
   318    998   BUILDDIRTOP = Debug
   319    999   !else
   320   1000   BUILDDIRTOP = Release
   321   1001   !endif
   322   1002   
................................................................................
   333   1013   
   334   1014   TMP_DIRFULL = .\$(BUILDDIRTOP)\$(PROJECT)_ThreadedDynamicStaticX
   335   1015   
   336   1016   !if !$(STATIC_BUILD)
   337   1017   TMP_DIRFULL = $(TMP_DIRFULL:Static=)
   338   1018   SUFX	    = $(SUFX:s=)
   339   1019   EXT	    = dll
   340         -!if $(MSVCRT)
   341   1020   TMP_DIRFULL = $(TMP_DIRFULL:X=)
   342   1021   SUFX	    = $(SUFX:x=)
   343         -!endif
   344   1022   !else
   345   1023   TMP_DIRFULL = $(TMP_DIRFULL:Dynamic=)
   346   1024   EXT	    = lib
   347   1025   !if !$(MSVCRT)
   348   1026   TMP_DIRFULL = $(TMP_DIRFULL:X=)
   349   1027   SUFX	    = $(SUFX:x=)
   350   1028   !endif
................................................................................
   362   1040   !endif
   363   1041   !else
   364   1042   !ifndef OUT_DIR
   365   1043   OUT_DIR	    = $(TMP_DIR)
   366   1044   !endif
   367   1045   !endif
   368   1046   
   369         -
   370         -#----------------------------------------------------------
   371         -# Decode the statistics requested.
   372         -#----------------------------------------------------------
   373         -
   374         -!if "$(STATS)" == "" || [nmakehlp -f "$(STATS)" "none"]
   375         -TCL_MEM_DEBUG	    = 0
   376         -TCL_COMPILE_DEBUG   = 0
   377         -!else
   378         -!if [nmakehlp -f $(STATS) "memdbg"]
   379         -!message *** Doing memdbg
   380         -TCL_MEM_DEBUG	    = 1
   381         -!else
   382         -TCL_MEM_DEBUG	    = 0
   383         -!endif
   384         -!if [nmakehlp -f $(STATS) "compdbg"]
   385         -!message *** Doing compdbg
   386         -TCL_COMPILE_DEBUG   = 1
         1047  +# Relative paths -> absolute
         1048  +!if [echo OUT_DIR = \> nmakehlp.out] \
         1049  +   || [nmakehlp -Q "$(OUT_DIR)" >> nmakehlp.out]
         1050  +!error *** Could not fully qualify path OUT_DIR=$(OUT_DIR)
         1051  +!endif
         1052  +!if [echo TMP_DIR = \>> nmakehlp.out] \
         1053  +   || [nmakehlp -Q "$(TMP_DIR)" >> nmakehlp.out]
         1054  +!error *** Could not fully qualify path TMP_DIR=$(TMP_DIR)
         1055  +!endif
         1056  +!include nmakehlp.out
         1057  +
         1058  +# The name of the stubs library for the project being built
         1059  +STUBPREFIX      = $(PROJECT)stub
         1060  +
         1061  +# Set up paths to various Tcl executables and libraries needed by extensions
         1062  +!if $(DOING_TCL)
         1063  +
         1064  +TCLSHNAME       = $(PROJECT)sh$(TCL_VERSION)$(SUFX).exe
         1065  +TCLSH		= $(OUT_DIR)\$(TCLSHNAME)
         1066  +TCLIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
         1067  +TCLLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
         1068  +TCLLIB		= $(OUT_DIR)\$(TCLLIBNAME)
         1069  +
         1070  +TCLSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
         1071  +TCLSTUBLIB	= $(OUT_DIR)\$(TCLSTUBLIBNAME)
         1072  +TCL_INCLUDES    = -I"$(WINDIR)" -I"$(GENERICDIR)"
         1073  +
         1074  +!else # ! $(DOING_TCL)
         1075  +
         1076  +!if $(TCLINSTALL) # Building against an installed Tcl
         1077  +
         1078  +# When building extensions, we need to locate tclsh. Depending on version
         1079  +# of Tcl we are building against, this may or may not have a "t" suffix.
         1080  +# Try various possibilities in turn.
         1081  +TCLSH		= $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe
         1082  +!if !exist("$(TCLSH)") && $(TCL_THREADS)
         1083  +TCLSH           = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe
         1084  +!endif
         1085  +!if !exist("$(TCLSH)")
         1086  +TCLSH           = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe
         1087  +!endif
         1088  +
         1089  +TCLSTUBLIB	= $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib
         1090  +TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib
         1091  +# When building extensions, may be linking against Tcl that does not add
         1092  +# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
         1093  +!if !exist("$(TCLIMPLIB)")
         1094  +TCLIMPLIB	= $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib
         1095  +!endif
         1096  +TCL_LIBRARY	= $(_TCLDIR)\lib
         1097  +TCLREGLIB	= $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib
         1098  +TCLDDELIB	= $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib
         1099  +TCLTOOLSDIR	= \must\have\tcl\sources\to\build\this\target
         1100  +TCL_INCLUDES    = -I"$(_TCLDIR)\include"
         1101  +
         1102  +!else # Building against Tcl sources
         1103  +
         1104  +TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe
         1105  +!if !exist($(TCLSH)) && $(TCL_THREADS)
         1106  +TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe
         1107  +!endif
         1108  +!if !exist($(TCLSH))
         1109  +TCLSH		= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe
         1110  +!endif
         1111  +TCLSTUBLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib
         1112  +TCLIMPLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib
         1113  +# When building extensions, may be linking against Tcl that does not add
         1114  +# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
         1115  +!if !exist("$(TCLIMPLIB)")
         1116  +TCLIMPLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib
         1117  +!endif
         1118  +TCL_LIBRARY	= $(_TCLDIR)\library
         1119  +TCLREGLIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib
         1120  +TCLDDELIB	= $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib
         1121  +TCLTOOLSDIR	= $(_TCLDIR)\tools
         1122  +TCL_INCLUDES	= -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
         1123  +
         1124  +!endif # TCLINSTALL
         1125  +
         1126  +tcllibs = "$(TCLSTUBLIB)" "$(TCLIMPLIB)"
         1127  +
         1128  +!endif # $(DOING_TCL)
         1129  +
         1130  +# We need a tclsh that will run on the host machine as part of the build.
         1131  +# IX86 runs on all architectures.
         1132  +!ifndef TCLSH_NATIVE
         1133  +!if "$(MACHINE)" == "IX86" || "$(MACHINE)" == "$(NATIVE_ARCH)"
         1134  +TCLSH_NATIVE	= $(TCLSH)
   387   1135   !else
   388         -TCL_COMPILE_DEBUG   = 0
   389         -!endif
   390         -!endif
   391         -
   392         -
   393         -#----------------------------------------------------------
   394         -# Decode the checks requested.
   395         -#----------------------------------------------------------
   396         -
   397         -!if "$(CHECKS)" == "" || [nmakehlp -f "$(CHECKS)" "none"]
   398         -TCL_NO_DEPRECATED	    = 0
   399         -WARNINGS		    = -W3
         1136  +!error You must explicitly set TCLSH_NATIVE for cross-compilation
         1137  +!endif
         1138  +!endif
         1139  +
         1140  +# Do the same for Tk and Tk extensions that require the Tk libraries
         1141  +!if $(DOING_TK) || $(NEED_TK)
         1142  +WISHNAMEPREFIX = wish
         1143  +WISHNAME = $(WISHNAMEPREFIX)$(TK_VERSION)$(SUFX).exe
         1144  +TKLIBNAME	= $(PROJECT)$(TK_VERSION)$(SUFX).$(EXT)
         1145  +TKSTUBLIBNAME	= tkstub$(TK_VERSION).lib
         1146  +TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX).lib
         1147  +
         1148  +!if $(DOING_TK)
         1149  +WISH 		= $(OUT_DIR)\$(WISHNAME)
         1150  +TKSTUBLIB	= $(OUT_DIR)\$(TKSTUBLIBNAME)
         1151  +TKIMPLIB	= $(OUT_DIR)\$(TKIMPLIBNAME)
         1152  +TKLIB		= $(OUT_DIR)\$(TKLIBNAME)
         1153  +TK_INCLUDES    = -I"$(WINDIR)" -I"$(GENERICDIR)"
         1154  +
         1155  +!else # effectively NEED_TK
         1156  +
         1157  +!if $(TKINSTALL) # Building against installed Tk
         1158  +WISH		= $(_TKDIR)\bin\$(WISHNAME)
         1159  +TKSTUBLIB	= $(_TKDIR)\lib\$(TKSTUBLIBNAME)
         1160  +TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
         1161  +# When building extensions, may be linking against Tk that does not add
         1162  +# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
         1163  +!if !exist("$(TKIMPLIB)")
         1164  +TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX:t=).lib
         1165  +TKIMPLIB	= $(_TKDIR)\lib\$(TKIMPLIBNAME)
         1166  +!endif
         1167  +TK_INCLUDES     = -I"$(_TKDIR)\include"
         1168  +!else # Building against Tk sources
         1169  +WISH		= $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME)
         1170  +TKSTUBLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME)
         1171  +TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
         1172  +# When building extensions, may be linking against Tk that does not add
         1173  +# "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility.
         1174  +!if !exist("$(TKIMPLIB)")
         1175  +TKIMPLIBNAME	= tk$(TK_VERSION)$(SUFX:t=).lib
         1176  +TKIMPLIB	= $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME)
         1177  +!endif
         1178  +TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
         1179  +!endif # TKINSTALL
         1180  +tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)"
         1181  +
         1182  +!endif # $(DOING_TK)
         1183  +!endif # $(DOING_TK) || $(NEED_TK)
         1184  +
         1185  +# Various output paths
         1186  +PRJIMPLIB	= $(OUT_DIR)\$(PROJECT)$(VERSION)$(SUFX).lib
         1187  +PRJLIBNAME	= $(PROJECT)$(VERSION)$(SUFX).$(EXT)
         1188  +PRJLIB		= $(OUT_DIR)\$(PRJLIBNAME)
         1189  +
         1190  +PRJSTUBLIBNAME	= $(STUBPREFIX)$(VERSION).lib
         1191  +PRJSTUBLIB	= $(OUT_DIR)\$(PRJSTUBLIBNAME)
         1192  +
         1193  +# If extension parent makefile has not defined a resource definition file,
         1194  +# we will generate one from standard template.
         1195  +!if !$(DOING_TCL) && !$(DOING_TK) && !$(STATIC_BUILD)
         1196  +!ifdef RCFILE
         1197  +RESFILE = $(TMP_DIR)\$(RCFILE:.rc=.res)
   400   1198   !else
   401         -!if [nmakehlp -f $(CHECKS) "nodep"]
   402         -!message *** Doing nodep check
   403         -TCL_NO_DEPRECATED	    = 1
   404         -!else
   405         -TCL_NO_DEPRECATED	    = 0
   406         -!endif
   407         -!if [nmakehlp -f $(CHECKS) "fullwarn"]
   408         -!message *** Doing full warnings check
   409         -WARNINGS		    = -W4
   410         -!if [nmakehlp -l -warn:3]
   411         -LINKERFLAGS		    = $(LINKERFLAGS) -warn:3
   412         -!endif
   413         -!else
   414         -WARNINGS		    = -W3
   415         -!endif
   416         -!if [nmakehlp -f $(CHECKS) "64bit"] && [nmakehlp -c -Wp64]
   417         -!message *** Doing 64bit portability warnings
   418         -WARNINGS		    = $(WARNINGS) -Wp64
   419         -!endif
   420         -!endif
   421         -
   422         -#----------------------------------------------------------
   423         -# Set our defines now armed with our options.
   424         -#----------------------------------------------------------
         1199  +RESFILE = $(TMP_DIR)\$(PROJECT).res
         1200  +!endif
         1201  +!endif
         1202  +
         1203  +###################################################################
         1204  +# 11. Construct the paths for the installation directories
         1205  +# The following macros get defined in this section:
         1206  +# LIB_INSTALL_DIR - where libraries should be installed
         1207  +# BIN_INSTALL_DIR - where the executables should be installed
         1208  +# DOC_INSTALL_DIR - where documentation should be installed
         1209  +# SCRIPT_INSTALL_DIR - where scripts should be installed
         1210  +# INCLUDE_INSTALL_DIR - where C include files should be installed
         1211  +# DEMO_INSTALL_DIR - where demos should be installed
         1212  +# PRJ_INSTALL_DIR - where package will be installed (not set for tcl and tk)
         1213  +
         1214  +!if $(DOING_TCL) || $(DOING_TK)
         1215  +LIB_INSTALL_DIR		= $(_INSTALLDIR)\lib
         1216  +BIN_INSTALL_DIR		= $(_INSTALLDIR)\bin
         1217  +DOC_INSTALL_DIR		= $(_INSTALLDIR)\doc
         1218  +!if $(DOING_TCL)
         1219  +SCRIPT_INSTALL_DIR	= $(_INSTALLDIR)\lib\$(PROJECT)$(TCL_MAJOR_VERSION).$(TCL_MINOR_VERSION)
         1220  +!else # DOING_TK
         1221  +SCRIPT_INSTALL_DIR	= $(_INSTALLDIR)\lib\$(PROJECT)$(TK_MAJOR_VERSION).$(TK_MINOR_VERSION)
         1222  +!endif
         1223  +DEMO_INSTALL_DIR	= $(SCRIPT_INSTALL_DIR)\demos
         1224  +INCLUDE_INSTALL_DIR	= $(_INSTALLDIR)\include
         1225  +
         1226  +!else # extension other than Tk
         1227  +
         1228  +PRJ_INSTALL_DIR         = $(_INSTALLDIR)\$(PROJECT)$(DOTVERSION)
         1229  +LIB_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
         1230  +BIN_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
         1231  +DOC_INSTALL_DIR		= $(PRJ_INSTALL_DIR)
         1232  +SCRIPT_INSTALL_DIR	= $(PRJ_INSTALL_DIR)
         1233  +DEMO_INSTALL_DIR	= $(PRJ_INSTALL_DIR)\demos
         1234  +INCLUDE_INSTALL_DIR	= $(_TCLDIR)\include
         1235  +
         1236  +!endif
         1237  +
         1238  +###################################################################
         1239  +# 12. Set up actual options to be passed to the compiler and linker
         1240  +# Now we have all the information we need, set up the actual flags and
         1241  +# options that we will pass to the compiler and linker. The main
         1242  +# makefile should use these in combination with whatever other flags
         1243  +# and switches are specific to it.
         1244  +# The following macros are defined, names are for historical compatibility:
         1245  +# OPTDEFINES - /Dxxx C macro flags based on user-specified OPTS
         1246  +# COMPILERFLAGS - /Dxxx C macro flags independent of any configuration opttions
         1247  +# crt - Compiler switch that selects the appropriate C runtime
         1248  +# cdebug - Compiler switches related to debug AND optimizations
         1249  +# cwarn - Compiler switches that set warning levels
         1250  +# cflags - complete compiler switches (subsumes cdebug and cwarn)
         1251  +# ldebug - Linker switches controlling debug information and optimization
         1252  +# lflags - complete linker switches (subsumes ldebug) except subsystem type
         1253  +# dlllflags - complete linker switches to build DLLs (subsumes lflags)
         1254  +# conlflags - complete linker switches for console program (subsumes lflags)
         1255  +# guilflags - complete linker switches for GUI program (subsumes lflags)
         1256  +# baselibs - minimum Windows libraries required. Parent makefile can
         1257  +#    define PRJ_LIBS before including rules.rc if additional libs are needed
   425   1258   
   426   1259   OPTDEFINES	= -DTCL_CFGVAL_ENCODING=$(CFG_ENCODING) -DSTDC_HEADERS
   427   1260   
   428   1261   !if $(TCL_MEM_DEBUG)
   429   1262   OPTDEFINES	= $(OPTDEFINES) -DTCL_MEM_DEBUG
   430   1263   !endif
   431   1264   !if $(TCL_COMPILE_DEBUG)
................................................................................
   432   1265   OPTDEFINES	= $(OPTDEFINES) -DTCL_COMPILE_DEBUG -DTCL_COMPILE_STATS
   433   1266   !endif
   434   1267   !if $(TCL_THREADS)
   435   1268   OPTDEFINES	= $(OPTDEFINES) -DTCL_THREADS=1
   436   1269   !if $(USE_THREAD_ALLOC)
   437   1270   OPTDEFINES	= $(OPTDEFINES) -DUSE_THREAD_ALLOC=1
   438   1271   !endif
   439         -!if $(USE_THREAD_STORAGE)
   440         -OPTDEFINES	= $(OPTDEFINES) -DUSE_THREAD_STORAGE=1
   441         -!endif
   442   1272   !endif
   443   1273   !if $(STATIC_BUILD)
   444   1274   OPTDEFINES	= $(OPTDEFINES) -DSTATIC_BUILD
   445   1275   !endif
   446   1276   !if $(TCL_NO_DEPRECATED)
   447   1277   OPTDEFINES	= $(OPTDEFINES) -DTCL_NO_DEPRECATED
   448   1278   !endif
   449   1279   
   450         -!if $(DEBUG)
   451         -OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_DEBUG
   452         -!elseif $(OPTIMIZING)
         1280  +!if $(USE_STUBS)
         1281  +# Note we do not define USE_TCL_STUBS even when building tk since some
         1282  +# test targets in tk do not use stubs
         1283  +!if ! $(DOING_TCL)
         1284  +USE_STUBS_DEFS  = -DUSE_TCL_STUBS -DUSE_TCLOO_STUBS
         1285  +!if $(NEED_TK)
         1286  +USE_STUBS_DEFS  = $(USE_STUBS_DEFS) -DUSE_TK_STUBS
         1287  +!endif
         1288  +!endif
         1289  +!endif # USE_STUBS
         1290  +
         1291  +!if !$(DEBUG)
         1292  +OPTDEFINES	= $(OPTDEFINES) -DNDEBUG
         1293  +!if $(OPTIMIZING)
   453   1294   OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_OPTIMIZED
         1295  +!endif
   454   1296   !endif
   455   1297   !if $(PROFILE)
   456   1298   OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_PROFILED
   457   1299   !endif
   458         -!if "$(MACHINE)" == "IA64" || "$(MACHINE)" == "AMD64"
         1300  +!if "$(MACHINE)" == "AMD64"
   459   1301   OPTDEFINES	= $(OPTDEFINES) -DTCL_CFG_DO64BIT
   460   1302   !endif
   461         -
   462         -
   463         -#----------------------------------------------------------
   464         -# Get common info used when building extensions.
   465         -#----------------------------------------------------------
   466         -
   467         -!if "$(PROJECT)" != "tcl"
   468         -
   469         -# If INSTALLDIR set to tcl root dir then reset to the lib dir.
   470         -!if exist("$(_INSTALLDIR)\include\tcl.h")
   471         -_INSTALLDIR=$(_INSTALLDIR)\lib
         1303  +!if $(VCVERSION) < 1300
         1304  +OPTDEFINES	= $(OPTDEFINES) -DNO_STRTOI64
         1305  +!endif
         1306  +
         1307  +# _ATL_XP_TARGETING - Newer SDK's need this to build for XP
         1308  +COMPILERFLAGS  = /D_ATL_XP_TARGETING
         1309  +
         1310  +# Following is primarily for the benefit of extensions. Tcl 8.5 builds
         1311  +# Tcl without /DUNICODE, while 8.6 builds with it defined. When building
         1312  +# an extension, it is advisable (but not mandated) to use the same Windows
         1313  +# API as the Tcl build. This is accordingly defaulted below. A particular
         1314  +# extension can override this by pre-definining USE_WIDECHAR_API.
         1315  +!ifndef USE_WIDECHAR_API
         1316  +!if $(TCL_VERSION) > 85
         1317  +USE_WIDECHAR_API = 1
         1318  +!else
         1319  +USE_WIDECHAR_API = 0
         1320  +!endif
         1321  +!endif
         1322  +
         1323  +!if $(USE_WIDECHAR_API)
         1324  +COMPILERFLAGS = $(COMPILERFLAGS) /DUNICODE /D_UNICODE 
         1325  +!endif
         1326  +
         1327  +# Like the TEA system only set this non empty for non-Tk extensions
         1328  +# Note: some extensions use PACKAGE_NAME and others use PACKAGE_TCLNAME
         1329  +# so we pass both
         1330  +!if !$(DOING_TCL) && !$(DOING_TK)
         1331  +PKGNAMEFLAGS = -DPACKAGE_NAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
         1332  +               -DPACKAGE_TCLNAME="\"$(PRJ_PACKAGE_TCLNAME)\"" \
         1333  +               -DPACKAGE_VERSION="\"$(DOTVERSION)\"" \
         1334  +               -DMODULE_SCOPE=extern 
         1335  +!endif
         1336  +
         1337  +# crt picks the C run time based on selected OPTS
         1338  +!if $(MSVCRT)
         1339  +!if $(DEBUG) && !$(UNCHECKED)
         1340  +crt = -MDd
         1341  +!else
         1342  +crt = -MD
         1343  +!endif
         1344  +!else
         1345  +!if $(DEBUG) && !$(UNCHECKED)
         1346  +crt = -MTd
         1347  +!else
         1348  +crt = -MT
         1349  +!endif
         1350  +!endif
         1351  +
         1352  +# cdebug includes compiler options for debugging as well as optimization.
         1353  +!if $(DEBUG)
         1354  +
         1355  +# In debugging mode, optimizations need to be disabled
         1356  +cdebug = -Zi -Od $(DEBUGFLAGS)
         1357  +
         1358  +!else
         1359  +
         1360  +cdebug = $(OPTIMIZATIONS)
         1361  +!if $(SYMBOLS)
         1362  +cdebug = $(cdebug) -Zi
         1363  +!endif
         1364  +
         1365  +!endif # $(DEBUG)
         1366  +
         1367  +# cwarn includes default warning levels.
         1368  +cwarn = $(WARNINGS)
         1369  +
         1370  +!if "$(MACHINE)" == "AMD64"
         1371  +# Disable pointer<->int warnings related to cast between different sizes
         1372  +# There are a gadzillion of these due to use of ClientData and
         1373  +# clutter up compiler
         1374  +# output increasing chance of a real warning getting lost. So disable them.
         1375  +# Eventually some day, Tcl will be 64-bit clean.
         1376  +cwarn = $(cwarn) -wd4311 -wd4312
         1377  +!endif
         1378  +
         1379  +### Common compiler options that are architecture specific
         1380  +!if "$(MACHINE)" == "ARM"
         1381  +carch = -D_ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE
         1382  +!else
         1383  +carch =
         1384  +!endif
         1385  +
         1386  +!if $(DEBUG)
         1387  +# Turn warnings into errors
         1388  +cwarn = $(cwarn) -WX
         1389  +!endif
         1390  +
         1391  +INCLUDES = $(TCL_INCLUDES) $(TK_INCLUDES) $(PRJ_INCLUDES)
         1392  +!if !$(DOING_TCL) && !$(DOING_TK)
         1393  +INCLUDES = $(INCLUDES) -I"$(GENERICDIR)" -I"$(WINDIR)" -I"$(COMPATDIR)"
         1394  +!endif
         1395  +
         1396  +# These flags are defined roughly in the order of the pre-reform
         1397  +# rules.vc/makefile.vc to help visually compare that the pre- and
         1398  +# post-reform build logs
         1399  +
         1400  +# cflags contains generic flags used for building practically all object files
         1401  +cflags = -nologo -c $(COMPILERFLAGS) $(carch) $(cwarn) -Fp$(TMP_DIR)^\ $(cdebug)
         1402  +
         1403  +# appcflags contains $(cflags) and flags for building the application
         1404  +# object files (e.g. tclsh, or wish) pkgcflags contains $(cflags) plus
         1405  +# flags used for building shared object files The two differ in the
         1406  +# BUILD_$(PROJECT) macro which should be defined only for the shared
         1407  +# library *implementation* and not for its caller interface
         1408  +
         1409  +appcflags = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES) $(USE_STUBS_DEFS)
         1410  +appcflags_nostubs = $(cflags) $(crt) $(INCLUDES) $(TCL_DEFINES) $(PRJ_DEFINES) $(OPTDEFINES)
         1411  +pkgcflags = $(appcflags) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
         1412  +pkgcflags_nostubs = $(appcflags_nostubs) $(PKGNAMEFLAGS) -DBUILD_$(PROJECT)
         1413  +
         1414  +# stubscflags contains $(cflags) plus flags used for building a stubs
         1415  +# library for the package.  Note: -DSTATIC_BUILD is defined in
         1416  +# $(OPTDEFINES) only if the OPTS configuration indicates a static
         1417  +# library. However the stubs library is ALWAYS static hence included
         1418  +# here irrespective of the OPTS setting.
         1419  +#
         1420  +# TBD - tclvfs has a comment that stubs libs should not be compiled with -GL
         1421  +# without stating why. Tcl itself compiled stubs libs with this flag.
         1422  +# so we do not remove it from cflags. -GL may prevent extensions
         1423  +# compiled with one VC version to fail to link against stubs library
         1424  +# compiled with another VC version. Check for this and fix accordingly.
         1425  +stubscflags = $(cflags) $(PKGNAMEFLAGS) $(PRJ_DEFINES) $(OPTDEFINES) -Zl -DSTATIC_BUILD $(INCLUDES)
         1426  +
         1427  +# Link flags 
         1428  +
         1429  +!if $(DEBUG)
         1430  +ldebug	= -debug -debugtype:cv
         1431  +!else
         1432  +ldebug	= -release -opt:ref -opt:icf,3
         1433  +!if $(SYMBOLS)
         1434  +ldebug	= $(ldebug) -debug -debugtype:cv
         1435  +!endif
         1436  +!endif
         1437  +
         1438  +# Note: Profiling is currently only possible with the Visual Studio Enterprise
         1439  +!if $(PROFILE)
         1440  +ldebug= $(ldebug) -profile
         1441  +!endif
         1442  +
         1443  +### Declarations common to all linker versions 
         1444  +lflags	= -nologo -machine:$(MACHINE) $(LINKERFLAGS) $(ldebug)
         1445  +
         1446  +!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
         1447  +lflags	= $(lflags) -nodefaultlib:libucrt.lib
         1448  +!endif
         1449  +
         1450  +# Old linkers (Visual C++ 6 in particular) will link for fast loading
         1451  +# on Win98. Since we do not support Win98 any more, we specify nowin98
         1452  +# as recommended for NT and later. However, this is only required by
         1453  +# IX86 on older compilers and only needed if we are not doing a static build.
         1454  +
         1455  +!if "$(MACHINE)" == "IX86" && !$(STATIC_BUILD)
         1456  +!if [nmakehlp -l -opt:nowin98 $(LINKER_TESTFLAGS)]
         1457  +# Align sections for PE size savings.
         1458  +lflags	= $(lflags) -opt:nowin98
         1459  +!endif
         1460  +!endif
         1461  +
         1462  +dlllflags = $(lflags) -dll
         1463  +conlflags = $(lflags) -subsystem:console
         1464  +guilflags = $(lflags) -subsystem:windows
         1465  +
         1466  +# Libraries that are required for every image.
         1467  +# Extensions should define any additional libraries with $(PRJ_LIBS)
         1468  +winlibs   = kernel32.lib advapi32.lib
         1469  +
         1470  +!if $(NEED_TK)
         1471  +winlibs = $(winlibs) gdi32.lib user32.lib uxtheme.lib
         1472  +!endif
         1473  +
         1474  +# Avoid 'unresolved external symbol __security_cookie' errors.
         1475  +# c.f. http://support.microsoft.com/?id=894573
         1476  +!if "$(MACHINE)" == "AMD64"
         1477  +!if $(VCVERSION) > 1399 && $(VCVERSION) < 1500
         1478  +winlibs   = $(winlibs) bufferoverflowU.lib
         1479  +!endif
         1480  +!endif
         1481  +
         1482  +baselibs = $(winlibs) $(PRJ_LIBS)
         1483  +
         1484  +!if $(MSVCRT) && !($(DEBUG) && !$(UNCHECKED)) && $(VCVERSION) >= 1900
         1485  +baselibs   = $(baselibs) ucrt.lib
         1486  +!endif
         1487  +
         1488  +################################################################
         1489  +# 13. Define standard commands, common make targets and implicit rules
         1490  +
         1491  +CCPKGCMD = $(cc32) $(pkgcflags) -Fo$(TMP_DIR)^\
         1492  +CCAPPCMD = $(cc32) $(appcflags) -Fo$(TMP_DIR)^\
         1493  +CCSTUBSCMD = $(cc32) $(stubscflags) -Fo$(TMP_DIR)^\
         1494  +
         1495  +LIBCMD = $(lib32) -nologo $(LINKERFLAGS) -out:$@
         1496  +DLLCMD = $(link32) $(dlllflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
         1497  +
         1498  +CONEXECMD = $(link32) $(conlflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
         1499  +GUIEXECMD = $(link32) $(guilflags) -out:$@ $(baselibs) $(tcllibs) $(tklibs)
         1500  +RESCMD  = $(rc32) -fo $@ -r -i "$(GENERICDIR)" -i "$(TMP_DIR)" \
         1501  +	    $(TCL_INCLUDES) \
         1502  +	    -DDEBUG=$(DEBUG) -d UNCHECKED=$(UNCHECKED) \
         1503  +	    -DCOMMAVERSION=$(DOTVERSION:.=,),0 \
         1504  +	    -DDOTVERSION=\"$(DOTVERSION)\" \
         1505  +	    -DVERSION=\"$(VERSION)\" \
         1506  +	    -DSUFX=\"$(SUFX)\" \
         1507  +            -DPROJECT=\"$(PROJECT)\" \
         1508  +            -DPRJLIBNAME=\"$(PRJLIBNAME)\" 
         1509  +
         1510  +!ifndef DEFAULT_BUILD_TARGET
         1511  +DEFAULT_BUILD_TARGET = $(PROJECT)
   472   1512   !endif
   473   1513   
   474         -!if !defined(TCLDIR)
   475         -!if exist("$(_INSTALLDIR)\..\include\tcl.h")
   476         -TCLINSTALL	= 1
   477         -_TCLDIR		= $(_INSTALLDIR)\..
   478         -_TCL_H          = $(_INSTALLDIR)\..\include\tcl.h
   479         -TCLDIR          = $(_INSTALLDIR)\..
   480         -!else
   481         -MSG=^
   482         -Failed to find tcl.h.  Set the TCLDIR macro.
   483         -!error $(MSG)
   484         -!endif
   485         -!else
   486         -_TCLDIR	= $(TCLDIR:/=\)
   487         -!if exist("$(_TCLDIR)\include\tcl.h")
   488         -TCLINSTALL	= 1
   489         -_TCL_H          = $(_TCLDIR)\include\tcl.h
   490         -!elseif exist("$(_TCLDIR)\generic\tcl.h")
   491         -TCLINSTALL	= 0
   492         -_TCL_H          = $(_TCLDIR)\generic\tcl.h
   493         -!else
   494         -MSG =^
   495         -Failed to find tcl.h.  The TCLDIR macro does not appear correct.
   496         -!error $(MSG)
   497         -!endif
         1514  +default-target: $(DEFAULT_BUILD_TARGET)
         1515  +
         1516  +default-pkgindex:
         1517  +	@echo package ifneeded $(PRJ_PACKAGE_TCLNAME) $(DOTVERSION) \
         1518  +	    [list load [file join $$dir $(PRJLIBNAME)]] > $(OUT_DIR)\pkgIndex.tcl
         1519  +
         1520  +default-pkgindex-tea:
         1521  +	@if exist $(ROOT)\pkgIndex.tcl.in nmakehlp -s << $(ROOT)\pkgIndex.tcl.in > $(OUT_DIR)\pkgIndex.tcl
         1522  +@PACKAGE_VERSION@    $(DOTVERSION)
         1523  +@PACKAGE_NAME@       $(PRJ_PACKAGE_TCLNAME)
         1524  +@PACKAGE_TCLNAME@    $(PRJ_PACKAGE_TCLNAME)
         1525  +@PKG_LIB_FILE@       $(PRJLIBNAME)
         1526  +<<
         1527  +
         1528  +
         1529  +default-install: default-install-binaries default-install-libraries
         1530  +
         1531  +default-install-binaries: $(PRJLIB)
         1532  +	@echo Installing binaries to '$(SCRIPT_INSTALL_DIR)'
         1533  +	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
         1534  +	@$(CPY) $(PRJLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
         1535  +
         1536  +default-install-libraries: $(OUT_DIR)\pkgIndex.tcl
         1537  +	@echo Installing libraries to '$(SCRIPT_INSTALL_DIR)'
         1538  +	@if exist $(LIBDIR) $(CPY) $(LIBDIR)\*.tcl "$(SCRIPT_INSTALL_DIR)"
         1539  +	@echo Installing package index in '$(SCRIPT_INSTALL_DIR)'
         1540  +	@$(CPY) $(OUT_DIR)\pkgIndex.tcl $(SCRIPT_INSTALL_DIR)
         1541  +
         1542  +default-install-stubs:
         1543  +	@echo Installing stubs library to '$(SCRIPT_INSTALL_DIR)'
         1544  +	@if not exist "$(SCRIPT_INSTALL_DIR)" mkdir "$(SCRIPT_INSTALL_DIR)"
         1545  +	@$(CPY) $(PRJSTUBLIB) "$(SCRIPT_INSTALL_DIR)" >NUL
         1546  +
         1547  +default-install-docs-html:
         1548  +	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
         1549  +	@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
         1550  +	@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.html" "$(DOCDIR)\*.css" "$(DOCDIR)\*.png") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
         1551  +
         1552  +default-install-docs-n:
         1553  +	@echo Installing documentation files to '$(DOC_INSTALL_DIR)'
         1554  +	@if not exist "$(DOC_INSTALL_DIR)" mkdir "$(DOC_INSTALL_DIR)"
         1555  +	@if exist $(DOCDIR) for %f in ("$(DOCDIR)\*.n") do @$(COPY) %f "$(DOC_INSTALL_DIR)"
         1556  +
         1557  +default-install-demos:
         1558  +	@echo Installing demos to '$(DEMO_INSTALL_DIR)'
         1559  +	@if not exist "$(DEMO_INSTALL_DIR)" mkdir "$(DEMO_INSTALL_DIR)"
         1560  +	@if exist $(DEMODIR) $(CPYDIR) "$(DEMODIR)" "$(DEMO_INSTALL_DIR)"
         1561  +
         1562  +default-clean:
         1563  +	@echo Cleaning $(TMP_DIR)\* ...
         1564  +	@if exist $(TMP_DIR)\nul $(RMDIR) $(TMP_DIR)
         1565  +	@echo Cleaning $(WINDIR)\nmakehlp.obj, nmakehlp.exe ...
         1566  +	@if exist $(WINDIR)\nmakehlp.obj del $(WINDIR)\nmakehlp.obj
         1567  +	@if exist $(WINDIR)\nmakehlp.exe del $(WINDIR)\nmakehlp.exe
         1568  +	@if exist $(WINDIR)\nmakehlp.out del $(WINDIR)\nmakehlp.out
         1569  +	@echo Cleaning $(WINDIR)\nmhlp-out.txt ...
         1570  +	@if exist $(WINDIR)\nmhlp-out.txt del $(WINDIR)\nmhlp-out.txt
         1571  +	@echo Cleaning $(WINDIR)\_junk.pch ...
         1572  +	@if exist $(WINDIR)\_junk.pch del $(WINDIR)\_junk.pch
         1573  +	@echo Cleaning $(WINDIR)\vercl.x, vercl.i ...
         1574  +	@if exist $(WINDIR)\vercl.x del $(WINDIR)\vercl.x
         1575  +	@if exist $(WINDIR)\vercl.i del $(WINDIR)\vercl.i
         1576  +	@echo Cleaning $(WINDIR)\versions.vc, version.vc ...
         1577  +	@if exist $(WINDIR)\versions.vc del $(WINDIR)\versions.vc
         1578  +	@if exist $(WINDIR)\version.vc del $(WINDIR)\version.vc
         1579  +
         1580  +default-hose: default-clean
         1581  +	@echo Hosing $(OUT_DIR)\* ...
         1582  +	@if exist $(OUT_DIR)\nul $(RMDIR) $(OUT_DIR)
         1583  +
         1584  +# Only for backward compatibility
         1585  +default-distclean: default-hose
         1586  +
         1587  +default-setup:
         1588  +	@if not exist $(OUT_DIR)\nul mkdir $(OUT_DIR)
         1589  +	@if not exist $(TMP_DIR)\nul mkdir $(TMP_DIR)
         1590  +
         1591  +!if "$(TESTPAT)" != ""
         1592  +TESTFLAGS = $(TESTFLAGS) -file $(TESTPAT)
   498   1593   !endif
   499   1594   
   500         -!if [echo REM = This file is generated from rules.vc > version.vc]
   501         -!endif
   502         -!if exist("$(_TCL_H)")
   503         -!if [echo TCL_DOTVERSION = \>> version.vc] \
   504         -   && [nmakehlp -V "$(_TCL_H)" TCL_VERSION >> version.vc]
   505         -!endif
   506         -!endif
   507         -!include version.vc
   508         -TCL_VERSION	= $(TCL_DOTVERSION:.=)
         1595  +default-test: default-setup $(PROJECT)
         1596  +	@set TCLLIBPATH=$(OUT_DIR:\=/)
         1597  +	@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
         1598  +	cd "$(TESTDIR)" && $(DEBUGGER) $(TCLSH) all.tcl $(TESTFLAGS)
   509   1599   
   510         -!if $(TCLINSTALL)
   511         -TCLSH		= "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe"
   512         -!if !exist($(TCLSH)) && $(TCL_THREADS)
   513         -TCLSH           = "$(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe"
   514         -!endif
   515         -TCLSTUBLIB	= "$(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib"
   516         -TCLIMPLIB	= "$(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib"
   517         -TCL_LIBRARY	= $(_TCLDIR)\lib
   518         -TCL_INCLUDES    = -I"$(_TCLDIR)\include"
         1600  +default-shell: default-setup $(PROJECT)
         1601  +	@set TCLLIBPATH=$(OUT_DIR:\=/)
         1602  +	@if exist $(LIBDIR) for %f in ("$(LIBDIR)\*.tcl") do @$(COPY) %f "$(OUT_DIR)"
         1603  +	$(DEBUGGER) $(TCLSH)
         1604  +
         1605  +# Generation of Windows version resource 
         1606  +!ifdef RCFILE
         1607  +
         1608  +# Note: don't use $** in below rule because there may be other dependencies
         1609  +# and only the "master" rc must be passed to the resource compiler
         1610  +$(TMP_DIR)\$(PROJECT).res: $(RCDIR)\$(PROJECT).rc
         1611  +	$(RESCMD) $(RCDIR)\$(PROJECT).rc
         1612  +
   519   1613   !else
   520         -TCLSH		= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX).exe"
   521         -!if !exist($(TCLSH)) && $(TCL_THREADS)
   522         -TCLSH		= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe"
         1614  +
         1615  +# If parent makefile has not defined a resource definition file,
         1616  +# we will generate one from standard template.
         1617  +$(TMP_DIR)\$(PROJECT).res: $(TMP_DIR)\$(PROJECT).rc
         1618  +
         1619  +$(TMP_DIR)\$(PROJECT).rc:
         1620  +	@$(COPY) << $(TMP_DIR)\$(PROJECT).rc
         1621  +#include <winver.h>
         1622  +
         1623  +VS_VERSION_INFO VERSIONINFO
         1624  + FILEVERSION	COMMAVERSION
         1625  + PRODUCTVERSION	COMMAVERSION
         1626  + FILEFLAGSMASK	0x3fL
         1627  +#ifdef DEBUG
         1628  + FILEFLAGS	VS_FF_DEBUG
         1629  +#else
         1630  + FILEFLAGS	0x0L
         1631  +#endif
         1632  + FILEOS		VOS_NT_WINDOWS32
         1633  + FILETYPE	VFT_DLL
         1634  + FILESUBTYPE	0x0L
         1635  +BEGIN
         1636  +    BLOCK "StringFileInfo"
         1637  +    BEGIN
         1638  +        BLOCK "040904b0"
         1639  +        BEGIN
         1640  +            VALUE "FileDescription",  "Tcl extension " PROJECT
         1641  +            VALUE "OriginalFilename", PRJLIBNAME
         1642  +            VALUE "FileVersion",      DOTVERSION
         1643  +            VALUE "ProductName",      "Package " PROJECT " for Tcl"
         1644  +            VALUE "ProductVersion",   DOTVERSION 
         1645  +        END
         1646  +    END
         1647  +    BLOCK "VarFileInfo"
         1648  +    BEGIN
         1649  +        VALUE "Translation", 0x409, 1200
         1650  +    END
         1651  +END
         1652  +
         1653  +<<
         1654  +
         1655  +!endif # ifdef RCFILE
         1656  +
         1657  +!ifndef DISABLE_IMPLICIT_RULES
         1658  +DISABLE_IMPLICIT_RULES = 0
   523   1659   !endif
   524         -TCLSTUBLIB	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib"
   525         -TCLIMPLIB	= "$(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib"
   526         -TCL_LIBRARY	= $(_TCLDIR)\library
   527         -TCL_INCLUDES	= -I"$(_TCLDIR)\generic" -I"$(_TCLDIR)\win"
         1660  +
         1661  +!if !$(DISABLE_IMPLICIT_RULES)
         1662  +# Implicit rule definitions - only for building library objects. For stubs and
         1663  +# main application, the master makefile should define explicit rules.
         1664  +
         1665  +{$(ROOT)}.c{$(TMP_DIR)}.obj::
         1666  +	$(CCPKGCMD) @<<
         1667  +$<
         1668  +<<
         1669  +
         1670  +{$(WINDIR)}.c{$(TMP_DIR)}.obj::
         1671  +	$(CCPKGCMD) @<<
         1672  +$<
         1673  +<<
         1674  +
         1675  +{$(GENERICDIR)}.c{$(TMP_DIR)}.obj::
         1676  +	$(CCPKGCMD) @<<
         1677  +$<
         1678  +<<
         1679  +
         1680  +{$(COMPATDIR)}.c{$(TMP_DIR)}.obj::
         1681  +	$(CCPKGCMD) @<<
         1682  +$<
         1683  +<<
         1684  +
         1685  +{$(RCDIR)}.rc{$(TMP_DIR)}.res:
         1686  +	$(RESCMD) $<
         1687  +
         1688  +{$(WINDIR)}.rc{$(TMP_DIR)}.res:
         1689  +	$(RESCMD) $<
         1690  +
         1691  +{$(TMP_DIR)}.rc{$(TMP_DIR)}.res:
         1692  +	$(RESCMD) $<
         1693  +
         1694  +.SUFFIXES:
         1695  +.SUFFIXES:.c .rc
         1696  +
   528   1697   !endif
         1698  +
         1699  +################################################################
         1700  +# 14. Sanity check selected options against Tcl build options
         1701  +# When building an extension, certain configuration options should
         1702  +# match the ones used when Tcl was built. Here we check and
         1703  +# warn on a mismatch.
         1704  +!if ! $(DOING_TCL)
   529   1705   
         1706  +!if $(TCLINSTALL) # Building against an installed Tcl
         1707  +!if exist("$(_TCLDIR)\lib\nmake\tcl.nmake")
         1708  +TCLNMAKECONFIG = "$(_TCLDIR)\lib\nmake\tcl.nmake"
         1709  +!endif
         1710  +!else # ! $(TCLINSTALL) - building against Tcl source
         1711  +!if exist("$(OUT_DIR)\tcl.nmake")
         1712  +TCLNMAKECONFIG = "$(OUT_DIR)\tcl.nmake"
   530   1713   !endif
         1714  +!endif # TCLINSTALL
   531   1715   
   532         -#----------------------------------------------------------
   533         -# Optionally check for Tk info for building extensions.
   534         -#----------------------------------------------------------
   535         -
   536         -!ifdef PROJECT_REQUIRES_TK
   537         -!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
         1716  +!if $(CONFIG_CHECK)
         1717  +!ifdef TCLNMAKECONFIG
         1718  +!include $(TCLNMAKECONFIG)
   538   1719   
   539         -!if !defined(TKDIR)
   540         -!if exist("$(_INSTALLDIR)\..\include\tk.h")
   541         -TKINSTALL      = 1
   542         -_TKDIR         = $(_INSTALLDIR)\..
   543         -_TK_H          = $(_TKDIR)\include\tk.h
   544         -TKDIR          = $(_TKDIR)
   545         -!elseif exist("$(_TCLDIR)\include\tk.h")
   546         -TKINSTALL      = 1
   547         -_TKDIR         = $(_TCLDIR)
   548         -_TK_H          = $(_TKDIR)\include\tk.h
   549         -TKDIR          = $(_TKDIR)
         1720  +!if defined(CORE_MACHINE) && "$(CORE_MACHINE)" != "$(MACHINE)"
         1721  +!error ERROR: Build target ($(MACHINE)) does not match the Tcl library architecture ($(CORE_MACHINE)).
         1722  +!endif
         1723  +!if defined(CORE_USE_THREAD_ALLOC) && $(CORE_USE_THREAD_ALLOC) != $(USE_THREAD_ALLOC)
         1724  +!message WARNING: Value of USE_THREAD_ALLOC ($(USE_THREAD_ALLOC)) does not match its Tcl core value ($(CORE_USE_THREAD_ALLOC)).
   550   1725   !endif
   551         -!else
   552         -_TKDIR = $(TKDIR:/=\)
   553         -!if exist("$(_TKDIR)\include\tk.h")
   554         -TKINSTALL      = 1
   555         -_TK_H          = $(_TKDIR)\include\tk.h
   556         -!elseif exist("$(_TKDIR)\generic\tk.h")
   557         -TKINSTALL      = 0
   558         -_TK_H          = $(_TKDIR)\generic\tk.h
   559         -!else
   560         -MSG =^
   561         -Failed to find tk.h. The TKDIR macro does not appear correct.
   562         -!error $(MSG)
         1726  +!if defined(CORE_DEBUG) && $(CORE_DEBUG) != $(DEBUG)
         1727  +!message WARNING: Value of DEBUG ($(DEBUG)) does not match its Tcl library configuration ($(DEBUG)).
   563   1728   !endif
   564   1729   !endif
   565   1730   
   566         -!if defined(TKDIR)
   567         -TK_DOTVERSION = 8.4
   568         -!if exist("$(_TK_H)")
   569         -!if [echo TK_DOTVERSION = \>> version.vc] \
   570         -   && [nmakehlp -V "$(_TK_H)" TK_VERSION >> version.vc]
   571         -!endif
   572         -!endif
   573         -!include version.vc
   574         -TK_VERSION = $(TK_DOTVERSION:.=)
         1731  +!endif # TCLNMAKECONFIG
   575   1732   
   576         -!if $(TKINSTALL)
   577         -WISH		= "$(_TKDIR)\bin\wish$(TK_VERSION)$(SUFX).exe"
   578         -!if !exist($(WISH)) && $(TCL_THREADS)
   579         -WISH		= "$(_TKDIR)\bin\wish$(TK_VERSION)t$(SUFX).exe"
   580         -!endif
   581         -TKSTUBLIB	= "$(_TKDIR)\lib\tkstub$(TK_VERSION).lib"
   582         -TKIMPLIB	= "$(_TKDIR)\lib\tk$(TK_VERSION)$(SUFX).lib"
   583         -TK_INCLUDES     = -I"$(_TKDIR)\include"
   584         -TK_LIBRARY	= $(_TKDIR)\lib
   585         -!else
   586         -WISH		= "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)$(SUFX).exe"
   587         -!if !exist($(WISH)) && $(TCL_THREADS)
   588         -WISH		= "$(_TKDIR)\win\$(BUILDDIRTOP)\wish$(TCL_VERSION)t$(SUFX).exe"
   589         -!endif
   590         -TKSTUBLIB	= "$(_TKDIR)\win\$(BUILDDIRTOP)\tkstub$(TCL_VERSION).lib"
   591         -TKIMPLIB	= "$(_TKDIR)\win\$(BUILDDIRTOP)\tk$(TCL_VERSION)$(SUFX).lib"
   592         -TK_INCLUDES     = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib"
   593         -TK_LIBRARY	= $(_TKDIR)\library
   594         -!endif
   595         -
   596         -!endif
   597         -!endif
   598         -!endif
   599         -
   600         -
   601         -#----------------------------------------------------------
   602         -# Setup the fully qualified OUT_DIR path as OUT_DIR_PATH
   603         -#----------------------------------------------------------
   604         -!if [echo OUT_DIR_PATH = \>> version.vc] \
   605         -    && [nmakehlp -Q "$(OUT_DIR)" >> version.vc]
   606         -!endif
   607         -!include version.vc
         1733  +!endif # ! $(DOING_TCL)
   608   1734   
   609   1735   
   610   1736   #----------------------------------------------------------
   611   1737   # Display stats being used.
   612   1738   #----------------------------------------------------------
   613   1739   
         1740  +!if !$(DOING_TCL)
         1741  +!message *** Building against Tcl at '$(_TCLDIR)'
         1742  +!endif
         1743  +!if !$(DOING_TK) && $(NEED_TK)
         1744  +!message *** Building against Tk at '$(_TKDIR)'
         1745  +!endif
   614   1746   !message *** Intermediate directory will be '$(TMP_DIR)'
   615   1747   !message *** Output directory will be '$(OUT_DIR)'
         1748  +!message *** Installation, if selected, will be in '$(_INSTALLDIR)'
   616   1749   !message *** Suffix for binaries will be '$(SUFX)'
   617         -!message *** Optional defines are '$(OPTDEFINES)'
   618         -!message *** Compiler version $(VCVER). Target machine is $(MACHINE)
   619         -!message *** Compiler options '$(COMPILERFLAGS) $(OPTIMIZATIONS) $(DEBUGFLAGS) $(WARNINGS)'
   620         -!message *** Link options '$(LINKERFLAGS)'
         1750  +!message *** Compiler version $(VCVER). Target $(MACHINE), host $(NATIVE_ARCH).
   621   1751   
   622         -!endif
         1752  +!endif # ifdef _RULES_VC

Added undroid/DiffUtilTcl/win/targets.vc.

            1  +#------------------------------------------------------------- -*- makefile -*-
            2  +# targets.vc --
            3  +#
            4  +# Part of the nmake based build system for Tcl and its extensions.
            5  +# This file defines some standard targets for the convenience of extensions
            6  +# and can be optionally included by the extension makefile.
            7  +# See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs.
            8  +
            9  +$(PROJECT): setup pkgindex $(PRJLIB)
           10  +
           11  +!ifdef PRJ_STUBOBJS
           12  +$(PROJECT): $(PRJSTUBLIB)
           13  +$(PRJSTUBLIB): $(PRJ_STUBOBJS)
           14  +	$(LIBCMD) $**
           15  +
           16  +$(PRJ_STUBOBJS):
           17  +	$(CCSTUBSCMD) %s
           18  +!endif # PRJ_STUBOBJS
           19  +
           20  +!ifdef PRJ_MANIFEST
           21  +$(PROJECT): $(PRJLIB).manifest
           22  +$(PRJLIB).manifest: $(PRJ_MANIFEST)
           23  +	@nmakehlp -s << $** >$@
           24  +@MACHINE@	  $(MACHINE:IX86=X86)
           25  +<<
           26  +!endif
           27  +
           28  +!if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk"
           29  +$(PRJLIB): $(PRJ_OBJS) $(RESFILE)
           30  +!if $(STATIC_BUILD)
           31  +       $(LIBCMD) $**
           32  +!else
           33  +       $(DLLCMD) $**
           34  +       $(_VC_MANIFEST_EMBED_DLL)
           35  +!endif
           36  +       -@del $*.exp
           37  +!endif
           38  +
           39  +!if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != ""
           40  +$(PRJ_OBJS): $(PRJ_HEADERS)
           41  +!endif
           42  +
           43  +# If parent makefile has defined stub objects, add their installation
           44  +# to the default install
           45  +!if "$(PRJ_STUBOBJS)" != ""
           46  +default-install: default-install-stubs
           47  +!endif
           48  +
           49  +# Unlike the other default targets, these cannot be in rules.vc because
           50  +# the executed command depends on existence of macro PRJ_HEADERS_PUBLIC
           51  +# that the parent makefile will not define until after including rules-ext.vc
           52  +!if "$(PRJ_HEADERS_PUBLIC)" != ""
           53  +default-install: default-install-headers
           54  +default-install-headers:
           55  +	@echo Installing headers to '$(INCLUDE_INSTALL_DIR)'
           56  +	@for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)"
           57  +!endif
           58  +
           59  +!if "$(DISABLE_STANDARD_TARGETS)" == ""
           60  +DISABLE_STANDARD_TARGETS = 0
           61  +!endif
           62  +
           63  +!if "$(DISABLE_TARGET_setup)" == ""
           64  +DISABLE_TARGET_setup = 0
           65  +!endif
           66  +!if "$(DISABLE_TARGET_install)" == ""
           67  +DISABLE_TARGET_install = 0
           68  +!endif
           69  +!if "$(DISABLE_TARGET_clean)" == ""
           70  +DISABLE_TARGET_clean = 0
           71  +!endif
           72  +!if "$(DISABLE_TARGET_test)" == ""
           73  +DISABLE_TARGET_test = 0
           74  +!endif
           75  +!if "$(DISABLE_TARGET_shell)" == ""
           76  +DISABLE_TARGET_shell = 0
           77  +!endif
           78  +
           79  +!if !$(DISABLE_STANDARD_TARGETS)
           80  +!if !$(DISABLE_TARGET_setup)
           81  +setup: default-setup
           82  +!endif
           83  +!if !$(DISABLE_TARGET_install)
           84  +install: default-install
           85  +!endif
           86  +!if !$(DISABLE_TARGET_clean)
           87  +clean: default-clean
           88  +realclean: hose
           89  +hose: default-hose
           90  +distclean: realclean default-distclean
           91  +!endif
           92  +!if !$(DISABLE_TARGET_test)
           93  +test: default-test
           94  +!endif
           95  +!if !$(DISABLE_TARGET_shell)
           96  +shell: default-shell
           97  +!endif
           98  +!endif # DISABLE_STANDARD_TARGETS