mksqlite3c.tcl 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334
  1. #!/usr/bin/tclsh
  2. #
  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
  6. #
  7. # make target_source
  8. #
  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".
  16. #
  17. # After the "tsrc" directory has been created and populated, run
  18. # this script:
  19. #
  20. # tclsh mksqlite3c.tcl
  21. #
  22. # The amalgamated SQLite code will be written into sqlite3.c
  23. #
  24. # Begin by reading the "sqlite3.h" header file. Extract the version number
  25. # from in this file. The version number is needed to generate the header
  26. # comment of the amalgamation.
  27. #
  28. if {[lsearch $argv --nostatic]>=0} {
  29. set addstatic 0
  30. } else {
  31. set addstatic 1
  32. }
  33. if {[lsearch $argv --linemacros]>=0} {
  34. set linemacros 1
  35. } else {
  36. set linemacros 0
  37. }
  38. set in [open tsrc/sqlite3.h]
  39. set cnt 0
  40. set VERSION ?????
  41. while {![eof $in]} {
  42. set line [gets $in]
  43. if {$line=="" && [eof $in]} break
  44. incr cnt
  45. regexp {#define\s+SQLITE_VERSION\s+"(.*)"} $line all VERSION
  46. }
  47. close $in
  48. # Open the output file and write a header comment at the beginning
  49. # of the file.
  50. #
  51. set out [open sqlite3.c w]
  52. # Force the output to use unix line endings, even on Windows.
  53. fconfigure $out -translation lf
  54. set today [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S UTC" -gmt 1]
  55. puts $out [subst \
  56. {/******************************************************************************
  57. ** This file is an amalgamation of many separate C source files from SQLite
  58. ** version $VERSION. By combining all the individual C code files into this
  59. ** single large file, the entire code can be compiled as a single translation
  60. ** unit. This allows many compilers to do optimizations that would not be
  61. ** possible if the files were compiled separately. Performance improvements
  62. ** of 5% or more are commonly seen when SQLite is compiled as a single
  63. ** translation unit.
  64. **
  65. ** This file is all you need to compile SQLite. To use SQLite in other
  66. ** programs, you need this file and the "sqlite3.h" header file that defines
  67. ** the programming interface to the SQLite library. (If you do not have
  68. ** the "sqlite3.h" header file at hand, you will find a copy embedded within
  69. ** the text of this file. Search for "Begin file sqlite3.h" to find the start
  70. ** of the embedded sqlite3.h header file.) Additional code files may be needed
  71. ** if you want a wrapper to interface SQLite with your choice of programming
  72. ** language. The code for the "sqlite3" command-line shell is also in a
  73. ** separate file. This file contains only code for the core SQLite library.
  74. */
  75. #define SQLITE_CORE 1
  76. #define SQLITE_AMALGAMATION 1}]
  77. if {$addstatic} {
  78. puts $out \
  79. {#ifndef SQLITE_PRIVATE
  80. # define SQLITE_PRIVATE static
  81. #endif
  82. #ifndef SQLITE_API
  83. # define SQLITE_API
  84. #endif}
  85. }
  86. # These are the header files used by SQLite. The first time any of these
  87. # files are seen in a #include statement in the C code, include the complete
  88. # text of the file in-line. The file only needs to be included once.
  89. #
  90. foreach hdr {
  91. btree.h
  92. btreeInt.h
  93. fts3.h
  94. fts3Int.h
  95. fts3_hash.h
  96. fts3_tokenizer.h
  97. hash.h
  98. hwtime.h
  99. keywordhash.h
  100. mutex.h
  101. opcodes.h
  102. os_common.h
  103. os.h
  104. pager.h
  105. parse.h
  106. pcache.h
  107. rtree.h
  108. sqlite3ext.h
  109. sqlite3.h
  110. sqliteicu.h
  111. sqliteInt.h
  112. sqliteLimit.h
  113. vdbe.h
  114. vdbeInt.h
  115. wal.h
  116. } {
  117. set available_hdr($hdr) 1
  118. }
  119. set available_hdr(sqliteInt.h) 0
  120. set available_hdr(sqlite3.h) 0
  121. # 78 stars used for comment formatting.
  122. set s78 \
  123. {*****************************************************************************}
  124. # Insert a comment into the code
  125. #
  126. proc section_comment {text} {
  127. global out s78
  128. set n [string length $text]
  129. set nstar [expr {60 - $n}]
  130. set stars [string range $s78 0 $nstar]
  131. puts $out "/************** $text $stars/"
  132. }
  133. # Read the source file named $filename and write it into the
  134. # sqlite3.c output file. If any #include statements are seen,
  135. # process them appropriately.
  136. #
  137. proc copy_file {filename} {
  138. global seen_hdr available_hdr out addstatic linemacros
  139. set ln 0
  140. set tail [file tail $filename]
  141. section_comment "Begin file $tail"
  142. if {$linemacros} {puts $out "#line 1 \"$filename\""}
  143. set in [open $filename r]
  144. set varpattern {^[a-zA-Z][a-zA-Z_0-9 *]+(sqlite3[_a-zA-Z0-9]+)(\[|;| =)}
  145. set declpattern {[a-zA-Z][a-zA-Z_0-9 ]+ \**(sqlite3[_a-zA-Z0-9]+)\(}
  146. if {[file extension $filename]==".h"} {
  147. set declpattern " *$declpattern"
  148. }
  149. set declpattern ^$declpattern
  150. while {![eof $in]} {
  151. set line [gets $in]
  152. incr ln
  153. if {[regexp {^\s*#\s*include\s+["<]([^">]+)[">]} $line all hdr]} {
  154. if {[info exists available_hdr($hdr)]} {
  155. if {$available_hdr($hdr)} {
  156. if {$hdr!="os_common.h" && $hdr!="hwtime.h"} {
  157. set available_hdr($hdr) 0
  158. }
  159. section_comment "Include $hdr in the middle of $tail"
  160. copy_file tsrc/$hdr
  161. section_comment "Continuing where we left off in $tail"
  162. if {$linemacros} {puts $out "#line [expr {$ln+1}] \"$filename\""}
  163. }
  164. } elseif {![info exists seen_hdr($hdr)]} {
  165. set seen_hdr($hdr) 1
  166. puts $out $line
  167. } elseif {[regexp {/\*\s+amalgamator:\s+keep\s+\*/} $line]} {
  168. # This include file must be kept because there was a "keep"
  169. # directive inside of a line comment.
  170. puts $out $line
  171. } else {
  172. # Comment out the entire line, replacing any nested comment
  173. # begin/end markers with the harmless substring "**".
  174. puts $out "/* [string map [list /* ** */ **] $line] */"
  175. }
  176. } elseif {[regexp {^#ifdef __cplusplus} $line]} {
  177. puts $out "#if 0"
  178. } elseif {!$linemacros && [regexp {^#line} $line]} {
  179. # Skip #line directives.
  180. } elseif {$addstatic && ![regexp {^(static|typedef)} $line]} {
  181. regsub {^SQLITE_API } $line {} line
  182. if {[regexp $declpattern $line all funcname]} {
  183. # Add the SQLITE_PRIVATE or SQLITE_API keyword before functions.
  184. # so that linkage can be modified at compile-time.
  185. if {[regexp {^sqlite3_} $funcname]} {
  186. puts $out "SQLITE_API $line"
  187. } else {
  188. puts $out "SQLITE_PRIVATE $line"
  189. }
  190. } elseif {[regexp $varpattern $line all varname]} {
  191. # Add the SQLITE_PRIVATE before variable declarations or
  192. # definitions for internal use
  193. if {![regexp {^sqlite3_} $varname]} {
  194. regsub {^extern } $line {} line
  195. puts $out "SQLITE_PRIVATE $line"
  196. } else {
  197. if {[regexp {const char sqlite3_version\[\];} $line]} {
  198. set line {const char sqlite3_version[] = SQLITE_VERSION;}
  199. }
  200. regsub {^SQLITE_EXTERN } $line {} line
  201. puts $out "SQLITE_API $line"
  202. }
  203. } elseif {[regexp {^(SQLITE_EXTERN )?void \(\*sqlite3IoTrace\)} $line]} {
  204. regsub {^SQLITE_EXTERN } $line {} line
  205. puts $out "SQLITE_PRIVATE $line"
  206. } elseif {[regexp {^void \(\*sqlite3Os} $line]} {
  207. puts $out "SQLITE_PRIVATE $line"
  208. } else {
  209. puts $out $line
  210. }
  211. } else {
  212. puts $out $line
  213. }
  214. }
  215. close $in
  216. section_comment "End of $tail"
  217. }
  218. # Process the source files. Process files containing commonly
  219. # used subroutines first in order to help the compiler find
  220. # inlining opportunities.
  221. #
  222. foreach file {
  223. sqlite_config_rtthread.h
  224. sqlite3.h
  225. sqliteInt.h
  226. global.c
  227. ctime.c
  228. status.c
  229. date.c
  230. os.c
  231. fault.c
  232. mem0.c
  233. mem1.c
  234. mem2.c
  235. mem3.c
  236. mem5.c
  237. mutex.c
  238. mutex_noop.c
  239. mutex_rtthread.c
  240. malloc.c
  241. printf.c
  242. random.c
  243. utf.c
  244. util.c
  245. hash.c
  246. opcodes.c
  247. os_rtthread.c
  248. bitvec.c
  249. pcache.c
  250. pcache1.c
  251. rowset.c
  252. pager.c
  253. wal.c
  254. btmutex.c
  255. btree.c
  256. backup.c
  257. vdbemem.c
  258. vdbeaux.c
  259. vdbeapi.c
  260. vdbetrace.c
  261. vdbe.c
  262. vdbeblob.c
  263. vdbesort.c
  264. journal.c
  265. memjournal.c
  266. walker.c
  267. resolve.c
  268. expr.c
  269. alter.c
  270. analyze.c
  271. attach.c
  272. auth.c
  273. build.c
  274. callback.c
  275. delete.c
  276. func.c
  277. fkey.c
  278. insert.c
  279. legacy.c
  280. loadext.c
  281. pragma.c
  282. prepare.c
  283. select.c
  284. table.c
  285. trigger.c
  286. update.c
  287. vacuum.c
  288. vtab.c
  289. where.c
  290. parse.c
  291. tokenize.c
  292. complete.c
  293. main.c
  294. notify.c
  295. fts3.c
  296. fts3_aux.c
  297. fts3_expr.c
  298. fts3_hash.c
  299. fts3_porter.c
  300. fts3_tokenizer.c
  301. fts3_tokenizer1.c
  302. fts3_tokenize_vtab.c
  303. fts3_write.c
  304. fts3_snippet.c
  305. fts3_unicode.c
  306. fts3_unicode2.c
  307. rtree.c
  308. icu.c
  309. fts3_icu.c
  310. } {
  311. copy_file tsrc/$file
  312. }
  313. close $out