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