Merges crypto.h, crypto.c, and crypto_impl.c into sqlcipher.c
[sqlcipher.git] / tool / mksqlite3c.tcl
blob5cfcd6f0888c771e216ba4f931076a8134fbff90
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 [flags] [extra source files]
22 # The amalgamated SQLite code will be written into sqlite3.c
25 set help {Usage: tclsh mksqlite3c.tcl <options>
26 where <options> is zero or more of the following with these effects:
27 --nostatic => Do not generate with compile-time modifiable linkage.
28 --linemacros=? => Emit #line directives into output or not. (? = 1 or 0)
29 --useapicall => Prepend functions with SQLITE_APICALL or SQLITE_CDECL.
30 --srcdir $SRC => Specify the directory containing constituent sources.
31 --help => See this.
32 The value setting options default to --linemacros=1 and '--srcdir tsrc' .
35 # Begin by reading the "sqlite3.h" header file. Extract the version number
36 # from in this file. The version number is needed to generate the header
37 # comment of the amalgamation.
40 set addstatic 1
41 set linemacros 0
42 set useapicall 0
43 set enable_recover 0
44 set srcdir tsrc
45 set extrasrc [list]
47 for {set i 0} {$i<[llength $argv]} {incr i} {
48 set x [lindex $argv $i]
49 if {[regexp {^-?-enable-recover$} $x]} {
50 set enable_recover 1
51 } elseif {[regexp {^-?-nostatic$} $x]} {
52 set addstatic 0
53 } elseif {[regexp {^-?-linemacros(?:=([01]))?$} $x ma ulm]} {
54 if {$ulm == ""} {set ulm 1}
55 set linemacros $ulm
56 } elseif {[regexp {^-?-useapicall$} $x]} {
57 set useapicall 1
58 } elseif {[regexp {^-?-srcdir$} $x]} {
59 incr i
60 if {$i==[llength $argv]} {
61 error "No argument following $x"
63 set srcdir [lindex $argv $i]
64 } elseif {[regexp {^-?-((help)|\?)$} $x]} {
65 puts $help
66 exit 0
67 } elseif {[regexp {^-?-} $x]} {
68 error "unknown command-line option: $x"
69 } else {
70 lappend extrasrc $x
73 set in [open $srcdir/sqlite3.h]
74 set cnt 0
75 set VERSION ?????
76 while {![eof $in]} {
77 set line [gets $in]
78 if {$line=="" && [eof $in]} break
79 incr cnt
80 regexp {#define\s+SQLITE_VERSION\s+"(.*)"} $line all VERSION
82 close $in
84 # Open the output file and write a header comment at the beginning
85 # of the file.
87 set fname sqlite3.c
88 if {$enable_recover} { set fname sqlite3r.c }
89 set out [open $fname w]
90 # Force the output to use unix line endings, even on Windows.
91 fconfigure $out -translation lf
92 set today [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S UTC" -gmt 1]
93 puts $out [subst \
94 {/******************************************************************************
95 ** This file is an amalgamation of many separate C source files from SQLite
96 ** version $VERSION. By combining all the individual C code files into this
97 ** single large file, the entire code can be compiled as a single translation
98 ** unit. This allows many compilers to do optimizations that would not be
99 ** possible if the files were compiled separately. Performance improvements
100 ** of 5% or more are commonly seen when SQLite is compiled as a single
101 ** translation unit.
103 ** This file is all you need to compile SQLite. To use SQLite in other
104 ** programs, you need this file and the "sqlite3.h" header file that defines
105 ** the programming interface to the SQLite library. (If you do not have
106 ** the "sqlite3.h" header file at hand, you will find a copy embedded within
107 ** the text of this file. Search for "Begin file sqlite3.h" to find the start
108 ** of the embedded sqlite3.h header file.) Additional code files may be needed
109 ** if you want a wrapper to interface SQLite with your choice of programming
110 ** language. The code for the "sqlite3" command-line shell is also in a
111 ** separate file. This file contains only code for the core SQLite library.
112 **}]
113 set srcroot [file dirname [file dirname [info script]]]
114 if {$tcl_platform(platform)=="windows"} {
115 set vsrcprog src-verify.exe
116 } else {
117 set vsrcprog ./src-verify
119 if {[file executable $vsrcprog] && [file readable $srcroot/manifest]} {
120 set res [string trim [split [exec $vsrcprog -x $srcroot]] \n]
121 puts $out "** The content in this amalgamation comes from Fossil check-in"
122 puts -nonewline $out "** [string range [lindex $res 0] 0 35]"
123 if {[llength $res]==1} {
124 puts $out "."
125 } else {
126 puts $out " with changes in files:\n**"
127 foreach f [lrange $res 1 end] {
128 puts $out "** $f"
131 } else {
132 puts $out "** The origin of the sources used to build this amalgamation"
133 puts $out "** is unknown."
135 puts $out [subst {*/
136 #define SQLITE_CORE 1
137 #define SQLITE_AMALGAMATION 1}]
138 if {$addstatic} {
139 puts $out \
140 {#ifndef SQLITE_PRIVATE
141 # define SQLITE_PRIVATE static
142 #endif}
145 # Examine the parse.c file. If it contains lines of the form:
147 # "#ifndef SQLITE_ENABLE_UPDATE_LIMIT
149 # then set the SQLITE_UDL_CAPABLE_PARSER flag in the amalgamation.
151 set in [open $srcdir/parse.c]
152 if {[regexp {ifndef SQLITE_ENABLE_UPDATE_DELETE_LIMIT} [read $in]]} {
153 puts $out "#define SQLITE_UDL_CAPABLE_PARSER 1"
155 close $in
157 # These are the header files used by SQLite. The first time any of these
158 # files are seen in a #include statement in the C code, include the complete
159 # text of the file in-line. The file only needs to be included once.
161 foreach hdr {
162 sqlcipher.h
163 btree.h
164 btreeInt.h
165 fts3.h
166 fts3Int.h
167 fts3_hash.h
168 fts3_tokenizer.h
169 geopoly.c
170 hash.h
171 hwtime.h
172 keywordhash.h
173 msvc.h
174 mutex.h
175 opcodes.h
176 os_common.h
177 os_setup.h
178 os_win.h
179 os.h
180 pager.h
181 parse.h
182 pcache.h
183 pragma.h
184 rtree.h
185 sqlite3session.h
186 sqlite3.h
187 sqlite3ext.h
188 sqlite3rbu.h
189 sqliteicu.h
190 sqliteInt.h
191 sqliteLimit.h
192 vdbe.h
193 vdbeInt.h
194 vxworks.h
195 wal.h
196 whereInt.h
197 sqlite3recover.h
199 set available_hdr($hdr) 1
201 set available_hdr(sqliteInt.h) 0
202 set available_hdr(os_common.h) 0
203 set available_hdr(sqlite3session.h) 0
205 # These headers should be copied into the amalgamation without modifying any
206 # of their function declarations or definitions.
207 set varonly_hdr(sqlite3.h) 1
209 # These are the functions that accept a variable number of arguments. They
210 # always need to use the "cdecl" calling convention even when another calling
211 # convention (e.g. "stcall") is being used for the rest of the library.
212 set cdecllist {
213 sqlite3_config
214 sqlite3_db_config
215 sqlite3_log
216 sqlite3_mprintf
217 sqlite3_snprintf
218 sqlite3_test_control
219 sqlite3_vtab_config
222 # 78 stars used for comment formatting.
223 set s78 \
224 {*****************************************************************************}
226 # Insert a comment into the code
228 proc section_comment {text} {
229 global out s78
230 set n [string length $text]
231 set nstar [expr {60 - $n}]
232 set stars [string range $s78 0 $nstar]
233 puts $out "/************** $text $stars/"
236 # Read the source file named $filename and write it into the
237 # sqlite3.c output file. If any #include statements are seen,
238 # process them appropriately.
240 proc copy_file {filename} {
241 global seen_hdr available_hdr varonly_hdr cdecllist out
242 global addstatic linemacros useapicall srcdir
243 set ln 0
244 set tail [file tail $filename]
245 section_comment "Begin file $tail"
246 if {$linemacros} {puts $out "#line 1 \"$filename\""}
247 set in [open $filename r]
248 set varpattern {^[a-zA-Z][a-zA-Z_0-9 *]+(sqlite3[_a-zA-Z0-9]+)(\[|;| =)}
249 set declpattern {([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3[_a-zA-Z0-9]+)(\(.*)}
250 if {[file extension $filename]==".h"} {
251 set declpattern " *$declpattern"
253 set declpattern ^$declpattern\$
254 while {![eof $in]} {
255 set line [string trimright [gets $in]]
256 incr ln
257 if {[regexp {^\s*#\s*include\s+["<]([^">]+)[">]} $line all hdr]} {
258 if {[info exists available_hdr($hdr)]} {
259 if {$available_hdr($hdr)} {
260 set available_hdr($hdr) 0
261 section_comment "Include $hdr in the middle of $tail"
262 copy_file $srcdir/$hdr
263 section_comment "Continuing where we left off in $tail"
264 if {$linemacros} {puts $out "#line [expr {$ln+1}] \"$filename\""}
265 } else {
266 # Comment out the entire line, replacing any nested comment
267 # begin/end markers with the harmless substring "**".
268 puts $out "/* [string map [list /* ** */ **] $line] */"
270 } elseif {![info exists seen_hdr($hdr)]} {
271 if {![regexp {/\*\s+amalgamator:\s+dontcache\s+\*/} $line]} {
272 set seen_hdr($hdr) 1
274 puts $out $line
275 } elseif {[regexp {/\*\s+amalgamator:\s+keep\s+\*/} $line]} {
276 # This include file must be kept because there was a "keep"
277 # directive inside of a line comment.
278 puts $out $line
279 } else {
280 # Comment out the entire line, replacing any nested comment
281 # begin/end markers with the harmless substring "**".
282 puts $out "/* [string map [list /* ** */ **] $line] */"
284 } elseif {[regexp {^#ifdef __cplusplus} $line]} {
285 puts $out "#if 0"
286 } elseif {!$linemacros && [regexp {^#line} $line]} {
287 # Skip #line directives.
288 } elseif {$addstatic
289 && ![regexp {^(static|typedef|SQLITE_PRIVATE)} $line]} {
290 # Skip adding the SQLITE_PRIVATE or SQLITE_API keyword before
291 # functions if this header file does not need it.
292 if {![info exists varonly_hdr($tail)]
293 && [regexp $declpattern $line all rettype funcname rest]} {
294 regsub {^SQLITE_API } $line {} line
295 regsub {^SQLITE_API } $rettype {} rettype
297 # Add the SQLITE_PRIVATE or SQLITE_API keyword before functions.
298 # so that linkage can be modified at compile-time.
299 if {[regexp {^sqlite3[a-z]*_} $funcname]} {
300 set line SQLITE_API
301 append line " " [string trim $rettype]
302 if {[string index $rettype end] ne "*"} {
303 append line " "
305 if {$useapicall} {
306 if {[lsearch -exact $cdecllist $funcname] >= 0} {
307 append line SQLITE_CDECL " "
308 } else {
309 append line SQLITE_APICALL " "
312 append line $funcname $rest
313 if {$funcname=="sqlite3_sourceid"} {
314 # The sqlite3_sourceid() routine is synthesized at the end of
315 # the amalgamation
316 puts $out "/* $line */"
317 } else {
318 puts $out $line
320 } else {
321 puts $out "SQLITE_PRIVATE $line"
323 } elseif {[regexp $varpattern $line all varname]} {
324 # Add the SQLITE_PRIVATE before variable declarations or
325 # definitions for internal use
326 regsub {^SQLITE_API } $line {} line
327 if {![regexp {^sqlite3_} $varname]
328 && ![regexp {^sqlite3Show[A-Z]} $varname]} {
329 regsub {^extern } $line {} line
330 puts $out "SQLITE_PRIVATE $line"
331 } else {
332 if {[regexp {const char sqlite3_version\[\];} $line]} {
333 set line {const char sqlite3_version[] = SQLITE_VERSION;}
335 regsub {^SQLITE_EXTERN } $line {} line
336 puts $out "SQLITE_API $line"
338 } elseif {[regexp {^(SQLITE_EXTERN )?void \(\*sqlite3IoTrace\)} $line]} {
339 regsub {^SQLITE_API } $line {} line
340 regsub {^SQLITE_EXTERN } $line {} line
341 puts $out $line
342 } elseif {[regexp {^void \(\*sqlite3Os} $line]} {
343 regsub {^SQLITE_API } $line {} line
344 puts $out "SQLITE_PRIVATE $line"
345 } else {
346 puts $out $line
348 } else {
349 puts $out $line
352 close $in
353 section_comment "End of $tail"
356 # Read the source file named $filename and write it into the
357 # sqlite3.c output file. The only transformation is the trimming
358 # of EOL whitespace.
360 proc copy_file_verbatim {filename} {
361 global out
362 set in [open $filename r]
363 set tail [file tail $filename]
364 section_comment "Begin EXTRA_SRC file $tail"
365 while {![eof $in]} {
366 set line [string trimright [gets $in]]
367 puts $out $line
369 section_comment "End of EXTRA_SRC $tail"
372 # Process the source files. Process files containing commonly
373 # used subroutines first in order to help the compiler find
374 # inlining opportunities.
376 set flist {
377 sqliteInt.h
378 os_common.h
379 ctime.c
381 global.c
382 status.c
383 date.c
384 os.c
386 fault.c
387 mem0.c
388 mem1.c
389 mem2.c
390 mem3.c
391 mem5.c
392 mutex.c
393 mutex_noop.c
394 mutex_unix.c
395 mutex_w32.c
396 malloc.c
397 printf.c
398 treeview.c
399 random.c
400 threads.c
401 utf.c
402 util.c
403 hash.c
404 opcodes.c
406 os_kv.c
407 os_unix.c
408 os_win.c
409 memdb.c
411 bitvec.c
412 pcache.c
413 pcache1.c
414 rowset.c
415 pager.c
416 wal.c
418 btmutex.c
419 btree.c
420 backup.c
422 vdbemem.c
423 vdbeaux.c
424 vdbeapi.c
425 vdbetrace.c
426 vdbe.c
427 vdbeblob.c
428 vdbesort.c
429 vdbevtab.c
430 memjournal.c
432 sqlcipher.c
433 crypto_libtomcrypt.c
434 crypto_nss.c
435 crypto_openssl.c
436 crypto_cc.c
438 walker.c
439 resolve.c
440 expr.c
441 alter.c
442 analyze.c
443 attach.c
444 auth.c
445 build.c
446 callback.c
447 delete.c
448 func.c
449 fkey.c
450 insert.c
451 legacy.c
452 loadext.c
453 pragma.c
454 prepare.c
455 select.c
456 table.c
457 trigger.c
458 update.c
459 upsert.c
460 vacuum.c
461 vtab.c
462 wherecode.c
463 whereexpr.c
464 where.c
465 window.c
467 parse.c
469 tokenize.c
470 complete.c
472 main.c
473 notify.c
475 fts3.c
476 fts3_aux.c
477 fts3_expr.c
478 fts3_hash.c
479 fts3_porter.c
480 fts3_tokenizer.c
481 fts3_tokenizer1.c
482 fts3_tokenize_vtab.c
483 fts3_write.c
484 fts3_snippet.c
485 fts3_unicode.c
486 fts3_unicode2.c
488 json.c
489 rtree.c
490 icu.c
492 fts3_icu.c
493 sqlite3rbu.c
494 dbstat.c
495 dbpage.c
496 sqlite3session.c
497 fts5.c
498 stmt.c
500 if {$enable_recover} {
501 lappend flist sqlite3recover.c dbdata.c
503 foreach file $flist {
504 copy_file $srcdir/$file
506 foreach file $extrasrc {
507 copy_file_verbatim $file
510 puts $out \
511 "/* Return the source-id for this library */
512 SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; }"
514 puts $out \
515 "/************************** End of sqlite3.c ******************************/"
517 close $out