Snapshot of upstream SQLite 3.11.0
[sqlcipher.git] / tool / mksqlite3c.tcl
blob23241e27a6ee4fa79e1c92f31c575f5c7a40b988
1 #!/usr/bin/tclsh
3 # To build a single huge source file holding all of SQLite (or at
4 # least the core components - the test harness, shell, and TCL
5 # interface are omitted.) first do
7 # make target_source
9 # The make target above moves all of the source code files into
10 # a subdirectory named "tsrc". (This script expects to find the files
11 # there and will not work if they are not found.) There are a few
12 # generated C code files that are also added to the tsrc directory.
13 # For example, the "parse.c" and "parse.h" files to implement the
14 # the parser are derived from "parse.y" using lemon. And the
15 # "keywordhash.h" files is generated by a program named "mkkeywordhash".
17 # After the "tsrc" directory has been created and populated, run
18 # this script:
20 # tclsh mksqlite3c.tcl --srcdir $SRC
22 # The amalgamated SQLite code will be written into sqlite3.c
25 # Begin by reading the "sqlite3.h" header file. Extract the version number
26 # from in this file. The version number is needed to generate the header
27 # comment of the amalgamation.
29 set addstatic 1
30 set linemacros 0
31 for {set i 0} {$i<[llength $argv]} {incr i} {
32 set x [lindex $argv $i]
33 if {[regexp {^-+nostatic$} $x]} {
34 set addstatic 0
35 } elseif {[regexp {^-+linemacros} $x]} {
36 set linemacros 1
37 } else {
38 error "unknown command-line option: $x"
41 set in [open tsrc/sqlite3.h]
42 set cnt 0
43 set VERSION ?????
44 while {![eof $in]} {
45 set line [gets $in]
46 if {$line=="" && [eof $in]} break
47 incr cnt
48 regexp {#define\s+SQLITE_VERSION\s+"(.*)"} $line all VERSION
50 close $in
52 # Open the output file and write a header comment at the beginning
53 # of the file.
55 set out [open sqlite3.c w]
56 # Force the output to use unix line endings, even on Windows.
57 fconfigure $out -translation lf
58 set today [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S UTC" -gmt 1]
59 puts $out [subst \
60 {/******************************************************************************
61 ** This file is an amalgamation of many separate C source files from SQLite
62 ** version $VERSION. By combining all the individual C code files into this
63 ** single large file, the entire code can be compiled as a single translation
64 ** unit. This allows many compilers to do optimizations that would not be
65 ** possible if the files were compiled separately. Performance improvements
66 ** of 5% or more are commonly seen when SQLite is compiled as a single
67 ** translation unit.
69 ** This file is all you need to compile SQLite. To use SQLite in other
70 ** programs, you need this file and the "sqlite3.h" header file that defines
71 ** the programming interface to the SQLite library. (If you do not have
72 ** the "sqlite3.h" header file at hand, you will find a copy embedded within
73 ** the text of this file. Search for "Begin file sqlite3.h" to find the start
74 ** of the embedded sqlite3.h header file.) Additional code files may be needed
75 ** if you want a wrapper to interface SQLite with your choice of programming
76 ** language. The code for the "sqlite3" command-line shell is also in a
77 ** separate file. This file contains only code for the core SQLite library.
79 #define SQLITE_CORE 1
80 #define SQLITE_AMALGAMATION 1}]
81 if {$addstatic} {
82 puts $out \
83 {#ifndef SQLITE_PRIVATE
84 # define SQLITE_PRIVATE static
85 #endif}
88 # These are the header files used by SQLite. The first time any of these
89 # files are seen in a #include statement in the C code, include the complete
90 # text of the file in-line. The file only needs to be included once.
92 foreach hdr {
93 btree.h
94 btreeInt.h
95 fts3.h
96 fts3Int.h
97 fts3_hash.h
98 fts3_tokenizer.h
99 hash.h
100 hwtime.h
101 keywordhash.h
102 msvc.h
103 mutex.h
104 opcodes.h
105 os_common.h
106 os_setup.h
107 os_win.h
108 os.h
109 pager.h
110 parse.h
111 pcache.h
112 pragma.h
113 rtree.h
114 sqlite3.h
115 sqlite3ext.h
116 sqlite3rbu.h
117 sqliteicu.h
118 sqliteInt.h
119 sqliteLimit.h
120 vdbe.h
121 vdbeInt.h
122 vxworks.h
123 wal.h
124 whereInt.h
126 set available_hdr($hdr) 1
128 set available_hdr(sqliteInt.h) 0
130 # These headers should be copied into the amalgamation without modifying any
131 # of their function declarations or definitions.
132 set varonly_hdr(sqlite3.h) 1
134 # These are the functions that accept a variable number of arguments. They
135 # always need to use the "cdecl" calling convention even when another calling
136 # convention (e.g. "stcall") is being used for the rest of the library.
137 set cdecllist {
138 sqlite3_config
139 sqlite3_db_config
140 sqlite3_log
141 sqlite3_mprintf
142 sqlite3_snprintf
143 sqlite3_test_control
144 sqlite3_vtab_config
147 # 78 stars used for comment formatting.
148 set s78 \
149 {*****************************************************************************}
151 # Insert a comment into the code
153 proc section_comment {text} {
154 global out s78
155 set n [string length $text]
156 set nstar [expr {60 - $n}]
157 set stars [string range $s78 0 $nstar]
158 puts $out "/************** $text $stars/"
161 # Read the source file named $filename and write it into the
162 # sqlite3.c output file. If any #include statements are seen,
163 # process them appropriately.
165 proc copy_file {filename} {
166 global seen_hdr available_hdr varonly_hdr cdecllist out addstatic linemacros
167 set ln 0
168 set tail [file tail $filename]
169 section_comment "Begin file $tail"
170 if {$linemacros} {puts $out "#line 1 \"$filename\""}
171 set in [open $filename r]
172 set varpattern {^[a-zA-Z][a-zA-Z_0-9 *]+(sqlite3[_a-zA-Z0-9]+)(\[|;| =)}
173 set declpattern {([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3[_a-zA-Z0-9]+)(\(.*)}
174 if {[file extension $filename]==".h"} {
175 set declpattern " *$declpattern"
177 set declpattern ^$declpattern\$
178 while {![eof $in]} {
179 set line [gets $in]
180 incr ln
181 if {[regexp {^\s*#\s*include\s+["<]([^">]+)[">]} $line all hdr]} {
182 if {[info exists available_hdr($hdr)]} {
183 if {$available_hdr($hdr)} {
184 if {$hdr!="os_common.h" && $hdr!="hwtime.h"} {
185 set available_hdr($hdr) 0
187 section_comment "Include $hdr in the middle of $tail"
188 copy_file tsrc/$hdr
189 section_comment "Continuing where we left off in $tail"
190 if {$linemacros} {puts $out "#line [expr {$ln+1}] \"$filename\""}
191 } else {
192 # Comment out the entire line, replacing any nested comment
193 # begin/end markers with the harmless substring "**".
194 puts $out "/* [string map [list /* ** */ **] $line] */"
196 } elseif {![info exists seen_hdr($hdr)]} {
197 if {![regexp {/\*\s+amalgamator:\s+dontcache\s+\*/} $line]} {
198 set seen_hdr($hdr) 1
200 puts $out $line
201 } elseif {[regexp {/\*\s+amalgamator:\s+keep\s+\*/} $line]} {
202 # This include file must be kept because there was a "keep"
203 # directive inside of a line comment.
204 puts $out $line
205 } else {
206 # Comment out the entire line, replacing any nested comment
207 # begin/end markers with the harmless substring "**".
208 puts $out "/* [string map [list /* ** */ **] $line] */"
210 } elseif {[regexp {^#ifdef __cplusplus} $line]} {
211 puts $out "#if 0"
212 } elseif {!$linemacros && [regexp {^#line} $line]} {
213 # Skip #line directives.
214 } elseif {$addstatic
215 && ![regexp {^(static|typedef|SQLITE_PRIVATE)} $line]} {
216 # Skip adding the SQLITE_PRIVATE or SQLITE_API keyword before
217 # functions if this header file does not need it.
218 if {![info exists varonly_hdr($tail)]
219 && [regexp $declpattern $line all rettype funcname rest]} {
220 regsub {^SQLITE_API } $line {} line
221 # Add the SQLITE_PRIVATE or SQLITE_API keyword before functions.
222 # so that linkage can be modified at compile-time.
223 if {[regexp {^sqlite3(_|rbu_)} $funcname]} {
224 set line SQLITE_API
225 append line " " [string trim $rettype]
226 if {[string index $rettype end] ne "*"} {
227 append line " "
229 if {[lsearch -exact $cdecllist $funcname] >= 0} {
230 append line SQLITE_CDECL
231 } else {
232 append line SQLITE_STDCALL
234 append line " " $funcname $rest
235 puts $out $line
236 } else {
237 puts $out "SQLITE_PRIVATE $line"
239 } elseif {[regexp $varpattern $line all varname]} {
240 # Add the SQLITE_PRIVATE before variable declarations or
241 # definitions for internal use
242 regsub {^SQLITE_API } $line {} line
243 if {![regexp {^sqlite3_} $varname]} {
244 regsub {^extern } $line {} line
245 puts $out "SQLITE_PRIVATE $line"
246 } else {
247 if {[regexp {const char sqlite3_version\[\];} $line]} {
248 set line {const char sqlite3_version[] = SQLITE_VERSION;}
250 regsub {^SQLITE_EXTERN } $line {} line
251 puts $out "SQLITE_API $line"
253 } elseif {[regexp {^(SQLITE_EXTERN )?void \(\*sqlite3IoTrace\)} $line]} {
254 regsub {^SQLITE_API } $line {} line
255 regsub {^SQLITE_EXTERN } $line {} line
256 puts $out $line
257 } elseif {[regexp {^void \(\*sqlite3Os} $line]} {
258 regsub {^SQLITE_API } $line {} line
259 puts $out "SQLITE_PRIVATE $line"
260 } else {
261 puts $out $line
263 } else {
264 puts $out $line
267 close $in
268 section_comment "End of $tail"
272 # Process the source files. Process files containing commonly
273 # used subroutines first in order to help the compiler find
274 # inlining opportunities.
276 foreach file {
277 sqliteInt.h
279 global.c
280 ctime.c
281 status.c
282 date.c
283 os.c
285 fault.c
286 mem0.c
287 mem1.c
288 mem2.c
289 mem3.c
290 mem5.c
291 mutex.c
292 mutex_noop.c
293 mutex_unix.c
294 mutex_w32.c
295 malloc.c
296 printf.c
297 treeview.c
298 random.c
299 threads.c
300 utf.c
301 util.c
302 hash.c
303 opcodes.c
305 os_unix.c
306 os_win.c
308 bitvec.c
309 pcache.c
310 pcache1.c
311 rowset.c
312 pager.c
313 wal.c
315 btmutex.c
316 btree.c
317 backup.c
319 vdbemem.c
320 vdbeaux.c
321 vdbeapi.c
322 vdbetrace.c
323 vdbe.c
324 vdbeblob.c
325 vdbesort.c
326 journal.c
327 memjournal.c
329 walker.c
330 resolve.c
331 expr.c
332 alter.c
333 analyze.c
334 attach.c
335 auth.c
336 build.c
337 callback.c
338 delete.c
339 func.c
340 fkey.c
341 insert.c
342 legacy.c
343 loadext.c
344 pragma.c
345 prepare.c
346 select.c
347 table.c
348 trigger.c
349 update.c
350 vacuum.c
351 vtab.c
352 wherecode.c
353 whereexpr.c
354 where.c
356 parse.c
358 tokenize.c
359 complete.c
361 main.c
362 notify.c
364 fts3.c
365 fts3_aux.c
366 fts3_expr.c
367 fts3_hash.c
368 fts3_porter.c
369 fts3_tokenizer.c
370 fts3_tokenizer1.c
371 fts3_tokenize_vtab.c
372 fts3_write.c
373 fts3_snippet.c
374 fts3_unicode.c
375 fts3_unicode2.c
377 rtree.c
378 icu.c
379 fts3_icu.c
380 sqlite3rbu.c
381 dbstat.c
382 json1.c
383 fts5.c
385 copy_file tsrc/$file
388 close $out