mksqlite3c-noext.tcl 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  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-noext.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. set addstatic 1
  29. set linemacros 0
  30. set useapicall 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. } elseif {[regexp {^-+useapicall} $x]} {
  38. set useapicall 1
  39. } else {
  40. error "unknown command-line option: $x"
  41. }
  42. }
  43. set in [open tsrc/sqlite3.h]
  44. set cnt 0
  45. set VERSION ?????
  46. while {![eof $in]} {
  47. set line [gets $in]
  48. if {$line=="" && [eof $in]} break
  49. incr cnt
  50. regexp {#define\s+SQLITE_VERSION\s+"(.*)"} $line all VERSION
  51. }
  52. close $in
  53. # Open the output file and write a header comment at the beginning
  54. # of the file.
  55. #
  56. set out [open sqlite3.c w]
  57. # Force the output to use unix line endings, even on Windows.
  58. fconfigure $out -translation lf
  59. set today [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S UTC" -gmt 1]
  60. puts $out [subst \
  61. {/******************************************************************************
  62. ** This file is an amalgamation of many separate C source files from SQLite
  63. ** version $VERSION. By combining all the individual C code files into this
  64. ** single large file, the entire code can be compiled as a single translation
  65. ** unit. This allows many compilers to do optimizations that would not be
  66. ** possible if the files were compiled separately. Performance improvements
  67. ** of 5% or more are commonly seen when SQLite is compiled as a single
  68. ** translation unit.
  69. **
  70. ** This file is all you need to compile SQLite. To use SQLite in other
  71. ** programs, you need this file and the "sqlite3.h" header file that defines
  72. ** the programming interface to the SQLite library. (If you do not have
  73. ** the "sqlite3.h" header file at hand, you will find a copy embedded within
  74. ** the text of this file. Search for "Begin file sqlite3.h" to find the start
  75. ** of the embedded sqlite3.h header file.) Additional code files may be needed
  76. ** if you want a wrapper to interface SQLite with your choice of programming
  77. ** language. The code for the "sqlite3" command-line shell is also in a
  78. ** separate file. This file contains only code for the core SQLite library.
  79. */
  80. #define SQLITE_CORE 1
  81. #define SQLITE_AMALGAMATION 1}]
  82. if {$addstatic} {
  83. puts $out \
  84. {#ifndef SQLITE_PRIVATE
  85. # define SQLITE_PRIVATE static
  86. #endif}
  87. }
  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.
  91. #
  92. foreach hdr {
  93. btree.h
  94. btreeInt.h
  95. hash.h
  96. hwtime.h
  97. keywordhash.h
  98. msvc.h
  99. mutex.h
  100. opcodes.h
  101. os_common.h
  102. os_setup.h
  103. os_win.h
  104. os.h
  105. pager.h
  106. parse.h
  107. pcache.h
  108. pragma.h
  109. sqlite3.h
  110. sqlite3ext.h
  111. sqliteicu.h
  112. sqliteInt.h
  113. sqliteLimit.h
  114. vdbe.h
  115. vdbeInt.h
  116. vxworks.h
  117. wal.h
  118. whereInt.h
  119. } {
  120. set available_hdr($hdr) 1
  121. }
  122. set available_hdr(sqliteInt.h) 0
  123. # These headers should be copied into the amalgamation without modifying any
  124. # of their function declarations or definitions.
  125. set varonly_hdr(sqlite3.h) 1
  126. # These are the functions that accept a variable number of arguments. They
  127. # always need to use the "cdecl" calling convention even when another calling
  128. # convention (e.g. "stcall") is being used for the rest of the library.
  129. set cdecllist {
  130. sqlite3_config
  131. sqlite3_db_config
  132. sqlite3_log
  133. sqlite3_mprintf
  134. sqlite3_snprintf
  135. sqlite3_test_control
  136. sqlite3_vtab_config
  137. }
  138. # 78 stars used for comment formatting.
  139. set s78 \
  140. {*****************************************************************************}
  141. # Insert a comment into the code
  142. #
  143. proc section_comment {text} {
  144. global out s78
  145. set n [string length $text]
  146. set nstar [expr {60 - $n}]
  147. set stars [string range $s78 0 $nstar]
  148. puts $out "/************** $text $stars/"
  149. }
  150. # Read the source file named $filename and write it into the
  151. # sqlite3.c output file. If any #include statements are seen,
  152. # process them appropriately.
  153. #
  154. proc copy_file {filename} {
  155. global seen_hdr available_hdr varonly_hdr cdecllist out
  156. global addstatic linemacros useapicall
  157. set ln 0
  158. set tail [file tail $filename]
  159. section_comment "Begin file $tail"
  160. if {$linemacros} {puts $out "#line 1 \"$filename\""}
  161. set in [open $filename r]
  162. set varpattern {^[a-zA-Z][a-zA-Z_0-9 *]+(sqlite3[_a-zA-Z0-9]+)(\[|;| =)}
  163. set declpattern {([a-zA-Z][a-zA-Z_0-9 ]+ \**)(sqlite3[_a-zA-Z0-9]+)(\(.*)}
  164. if {[file extension $filename]==".h"} {
  165. set declpattern " *$declpattern"
  166. }
  167. set declpattern ^$declpattern\$
  168. while {![eof $in]} {
  169. set line [gets $in]
  170. incr ln
  171. if {[regexp {^\s*#\s*include\s+["<]([^">]+)[">]} $line all hdr]} {
  172. if {[info exists available_hdr($hdr)]} {
  173. if {$available_hdr($hdr)} {
  174. if {$hdr!="os_common.h" && $hdr!="hwtime.h"} {
  175. set available_hdr($hdr) 0
  176. }
  177. section_comment "Include $hdr in the middle of $tail"
  178. copy_file tsrc/$hdr
  179. section_comment "Continuing where we left off in $tail"
  180. if {$linemacros} {puts $out "#line [expr {$ln+1}] \"$filename\""}
  181. } else {
  182. # Comment out the entire line, replacing any nested comment
  183. # begin/end markers with the harmless substring "**".
  184. puts $out "/* [string map [list /* ** */ **] $line] */"
  185. }
  186. } elseif {![info exists seen_hdr($hdr)]} {
  187. if {![regexp {/\*\s+amalgamator:\s+dontcache\s+\*/} $line]} {
  188. set seen_hdr($hdr) 1
  189. }
  190. puts $out $line
  191. } elseif {[regexp {/\*\s+amalgamator:\s+keep\s+\*/} $line]} {
  192. # This include file must be kept because there was a "keep"
  193. # directive inside of a line comment.
  194. puts $out $line
  195. } else {
  196. # Comment out the entire line, replacing any nested comment
  197. # begin/end markers with the harmless substring "**".
  198. puts $out "/* [string map [list /* ** */ **] $line] */"
  199. }
  200. } elseif {[regexp {^#ifdef __cplusplus} $line]} {
  201. puts $out "#if 0"
  202. } elseif {!$linemacros && [regexp {^#line} $line]} {
  203. # Skip #line directives.
  204. } elseif {$addstatic
  205. && ![regexp {^(static|typedef|SQLITE_PRIVATE)} $line]} {
  206. # Skip adding the SQLITE_PRIVATE or SQLITE_API keyword before
  207. # functions if this header file does not need it.
  208. if {![info exists varonly_hdr($tail)]
  209. && [regexp $declpattern $line all rettype funcname rest]} {
  210. regsub {^SQLITE_API } $line {} line
  211. # Add the SQLITE_PRIVATE or SQLITE_API keyword before functions.
  212. # so that linkage can be modified at compile-time.
  213. if {[regexp {^sqlite3[a-z]*_} $funcname]} {
  214. set line SQLITE_API
  215. append line " " [string trim $rettype]
  216. if {[string index $rettype end] ne "*"} {
  217. append line " "
  218. }
  219. if {$useapicall} {
  220. if {[lsearch -exact $cdecllist $funcname] >= 0} {
  221. append line SQLITE_CDECL " "
  222. } else {
  223. append line SQLITE_APICALL " "
  224. }
  225. }
  226. append line $funcname $rest
  227. puts $out $line
  228. } else {
  229. puts $out "SQLITE_PRIVATE $line"
  230. }
  231. } elseif {[regexp $varpattern $line all varname]} {
  232. # Add the SQLITE_PRIVATE before variable declarations or
  233. # definitions for internal use
  234. regsub {^SQLITE_API } $line {} line
  235. if {![regexp {^sqlite3_} $varname]} {
  236. regsub {^extern } $line {} line
  237. puts $out "SQLITE_PRIVATE $line"
  238. } else {
  239. if {[regexp {const char sqlite3_version\[\];} $line]} {
  240. set line {const char sqlite3_version[] = SQLITE_VERSION;}
  241. }
  242. regsub {^SQLITE_EXTERN } $line {} line
  243. puts $out "SQLITE_API $line"
  244. }
  245. } elseif {[regexp {^(SQLITE_EXTERN )?void \(\*sqlite3IoTrace\)} $line]} {
  246. regsub {^SQLITE_API } $line {} line
  247. regsub {^SQLITE_EXTERN } $line {} line
  248. puts $out $line
  249. } elseif {[regexp {^void \(\*sqlite3Os} $line]} {
  250. regsub {^SQLITE_API } $line {} line
  251. puts $out "SQLITE_PRIVATE $line"
  252. } else {
  253. puts $out $line
  254. }
  255. } else {
  256. puts $out $line
  257. }
  258. }
  259. close $in
  260. section_comment "End of $tail"
  261. }
  262. # Process the source files. Process files containing commonly
  263. # used subroutines first in order to help the compiler find
  264. # inlining opportunities.
  265. #
  266. foreach file {
  267. sqliteInt.h
  268. global.c
  269. ctime.c
  270. status.c
  271. date.c
  272. os.c
  273. fault.c
  274. mem0.c
  275. mem1.c
  276. mem2.c
  277. mem3.c
  278. mem5.c
  279. mutex.c
  280. mutex_noop.c
  281. mutex_unix.c
  282. mutex_w32.c
  283. malloc.c
  284. printf.c
  285. treeview.c
  286. random.c
  287. threads.c
  288. utf.c
  289. util.c
  290. hash.c
  291. opcodes.c
  292. os_unix.c
  293. os_win.c
  294. bitvec.c
  295. pcache.c
  296. pcache1.c
  297. rowset.c
  298. pager.c
  299. wal.c
  300. btmutex.c
  301. btree.c
  302. backup.c
  303. vdbemem.c
  304. vdbeaux.c
  305. vdbeapi.c
  306. vdbetrace.c
  307. vdbe.c
  308. vdbeblob.c
  309. vdbesort.c
  310. memjournal.c
  311. walker.c
  312. resolve.c
  313. expr.c
  314. alter.c
  315. analyze.c
  316. attach.c
  317. auth.c
  318. build.c
  319. callback.c
  320. delete.c
  321. func.c
  322. fkey.c
  323. insert.c
  324. legacy.c
  325. loadext.c
  326. pragma.c
  327. prepare.c
  328. select.c
  329. table.c
  330. trigger.c
  331. update.c
  332. vacuum.c
  333. vtab.c
  334. wherecode.c
  335. whereexpr.c
  336. where.c
  337. window.c
  338. parse.c
  339. tokenize.c
  340. complete.c
  341. main.c
  342. notify.c
  343. } {
  344. copy_file tsrc/$file
  345. }
  346. close $out