1#!/usr/bin/tcl
2#
3# This script reads the regular MSVC makefile (../Makefile.msc) and outputs
4# a revised version of that Makefile that is "minimal" in the sense that
5# it uses the sqlite3.c amalgamation as input and does not require tclsh.
6# The resulting "../Makefile.min.msc" is suitable for use in the amalgamation
7# tarballs.
8#
9if {$argc==0} {
10  set basedir [file dir [file dir [file normalize $argv0]]]
11  set fromFileName [file join $basedir Makefile.msc]
12  set toFileName [file join $basedir autoconf Makefile.msc]
13} else {
14  set fromFileName [lindex $argv 0]
15  if {![file exists $fromFileName]} {
16    error "input file \"$fromFileName\" does not exist"
17  }
18  set toFileName [lindex $argv 1]
19  if {[file exists $toFileName]} {
20    error "output file \"$toFileName\" already exists"
21  }
22}
23
24proc readFile { fileName } {
25  set file_id [open $fileName RDONLY]
26  fconfigure $file_id -encoding binary -translation binary
27  set result [read $file_id]
28  close $file_id
29  return $result
30}
31
32proc writeFile { fileName data } {
33  set file_id [open $fileName {WRONLY CREAT TRUNC}]
34  fconfigure $file_id -encoding binary -translation binary
35  puts -nonewline $file_id $data
36  close $file_id
37  return ""
38}
39
40proc escapeSubSpec { data } {
41  regsub -all -- {&} $data {\\\&} data
42  regsub -all -- {\\(\d+)} $data {\\\\\1} data
43  return $data
44}
45
46proc substVars { data } {
47  return [uplevel 1 [list subst -nocommands -nobackslashes $data]]
48}
49
50#
51# NOTE: This block is used to replace the section marked <<block1>> in
52#       the Makefile, if it exists.
53#
54set blocks(1) [string trimleft [string map [list \\\\ \\] {
55_HASHCHAR=^#
56!IF ![echo !IFNDEF VERSION > rcver.vc] && \\
57    ![for /F "delims=" %V in ('type "$(SQLITE3H)" ^| "%SystemRoot%\System32\find.exe" "$(_HASHCHAR)define SQLITE_VERSION "') do (echo VERSION = ^^%V >> rcver.vc)] && \\
58    ![echo !ENDIF >> rcver.vc]
59!INCLUDE rcver.vc
60!ENDIF
61
62RESOURCE_VERSION = $(VERSION:^#=)
63RESOURCE_VERSION = $(RESOURCE_VERSION:define=)
64RESOURCE_VERSION = $(RESOURCE_VERSION:SQLITE_VERSION=)
65RESOURCE_VERSION = $(RESOURCE_VERSION:"=)
66RESOURCE_VERSION = $(RESOURCE_VERSION:.=,)
67
68$(LIBRESOBJS):	$(TOP)\sqlite3.rc rcver.vc $(SQLITE3H)
69	echo #ifndef SQLITE_RESOURCE_VERSION > sqlite3rc.h
70	echo #define SQLITE_RESOURCE_VERSION $(RESOURCE_VERSION) >> sqlite3rc.h
71	echo #endif >> sqlite3rc.h
72	$(LTRCOMPILE) -fo $(LIBRESOBJS) -DRC_VERONLY $(TOP)\sqlite3.rc
73}]]
74
75#
76# NOTE: This block is used to replace the section marked <<block2>> in
77#       the Makefile, if it exists.
78#
79set blocks(2) [string trimleft [string map [list \\\\ \\] {
80Replace.exe:
81	$(CSC) /target:exe $(TOP)\Replace.cs
82
83sqlite3.def:	Replace.exe $(LIBOBJ)
84	echo EXPORTS > sqlite3.def
85	dumpbin /all $(LIBOBJ) \\
86		| .\Replace.exe "^\s+/EXPORT:_?(sqlite3(?:session|changeset|changegroup|rebaser|rbu)?_[^@,]*)(?:@\d+|,DATA)?$$" $$1 true \\
87		| sort >> sqlite3.def
88}]]
89
90set data "#### DO NOT EDIT ####\n"
91append data "# This makefile is automatically "
92append data "generated from the [file tail $fromFileName] at\n"
93append data "# the root of the canonical SQLite source tree (not the\n"
94append data "# amalgamation tarball) using the tool/[file tail $argv0]\n"
95append data "# script.\n#\n\n"
96append data [readFile $fromFileName]
97
98regsub -all -- {# <<mark>>\n.*?# <</mark>>\n} \
99    $data "" data
100
101foreach i [lsort -integer [array names blocks]] {
102  regsub -all -- [substVars \
103      {# <<block${i}>>\n.*?# <</block${i}>>\n}] \
104      $data [escapeSubSpec $blocks($i)] data
105}
106
107set data [string map [list " -I\$(TOP)\\src" ""] $data]
108set data [string map [list " libsqlite3.lib" ""] $data]
109set data [string map [list " \$(ALL_TCL_TARGETS)" ""] $data]
110set data [string map [list "\$(TOP)\\src\\" "\$(TOP)\\"] $data]
111
112writeFile $toFileName $data
113