Home | History | Annotate | Line # | Download | only in tea
      1 # Teaish configure script for the SQLite Tcl extension
      2 
      3 #
      4 # State for disparate config-time pieces.
      5 #
      6 array set sqlite__Config [proj-strip-hash-comments {
      7   #
      8   # The list of feature --flags which the --all flag implies. This
      9   # requires special handling in a few places.
     10   #
     11   all-flag-enables {fts3 fts4 fts5 rtree geopoly}
     12 
     13   # >0 if building in the canonical tree. -1=undetermined
     14   is-canonical -1
     15 }]
     16 
     17 #
     18 # Set up the package info for teaish...
     19 #
     20 apply {{dir} {
     21   # Figure out the version number...
     22   set version ""
     23   if {[file exists $dir/../VERSION]} {
     24     # The canonical SQLite TEA(ish) build
     25     set version [proj-file-content -trim $dir/../VERSION]
     26     set ::sqlite__Config(is-canonical) 1
     27     set distname sqlite-tcl
     28   } elseif {[file exists $dir/generic/tclsqlite3.c]} {
     29     # The copy from the teaish tree, used as a dev/test bed before
     30     # updating SQLite's tree.
     31     set ::sqlite__Config(is-canonical) 0
     32     set fd [open $dir/generic/tclsqlite3.c rb]
     33     while {[gets $fd line] >=0} {
     34       if {[regexp {^#define[ ]+SQLITE_VERSION[ ]+"(3.+)"} \
     35              $line - version]} {
     36         set distname sqlite-teaish
     37         break
     38       }
     39     }
     40     close $fd
     41   }
     42 
     43   if {"" eq $version} {
     44     proj-fatal "Cannot determine the SQLite version number"
     45   }
     46 
     47   proj-assert {$::sqlite__Config(is-canonical) > -1}
     48   proj-assert {[string match 3.*.* $version]} \
     49     "Unexpected SQLite version: $version"
     50 
     51   set pragmas {}
     52   if {$::sqlite__Config(is-canonical)} {
     53     # Disable "make dist" in the canonical tree.  That tree is
     54     # generated from several pieces and creating/testing working
     55     # "dist" rules for that sub-build currently feels unnecessary. The
     56     # copy in the teaish tree, though, should be able to "make dist".
     57     lappend pragmas no-dist
     58   } else {
     59     lappend pragmas full-dist
     60   }
     61 
     62   teaish-pkginfo-set -vars {
     63     -name sqlite
     64     -name.pkg sqlite3
     65     -version $version
     66     -name.dist $distname
     67     -libDir sqlite$version
     68     -pragmas $pragmas
     69     -src generic/tclsqlite3.c
     70   }
     71   # We should also have:
     72   #    -vsatisfies 8.6-
     73   # But at least one platform is failing this vsatisfies check
     74   # for no apparent reason:
     75   # https://sqlite.org/forum/forumpost/fde857fb8101a4be
     76 }} [teaish-get -dir]
     77 
     78 
     79 #
     80 # Must return either an empty string or a list in the form accepted by
     81 # autosetup's [options] function.
     82 #
     83 proc teaish-options {} {
     84   # These flags and defaults mostly derive from the historical TEA
     85   # build.  Some, like ICU, are taken from the canonical SQLite tree.
     86   return [subst -nocommands -nobackslashes {
     87     with-system-sqlite=0
     88       => {Use the system-level SQLite instead of the copy in this tree.
     89           Also requires use of --override-sqlite-version so that the build
     90           knows what version number to associate with the system-level SQLite.}
     91     override-sqlite-version:VERSION
     92       => {For use with --with-system-sqlite to set the version number.}
     93     threadsafe=1         => {Disable mutexing}
     94     with-tempstore:=no   => {Use an in-RAM database for temporary tables: never,no,yes,always}
     95     load-extension=0     => {Enable loading of external extensions}
     96     math=1               => {Disable math functions}
     97     json=1               => {Disable JSON functions}
     98     fts3                 => {Enable the FTS3 extension}
     99     fts4                 => {Enable the FTS4 extension}
    100     fts5                 => {Enable the FTS5 extension}
    101     update-limit         => {Enable the UPDATE/DELETE LIMIT clause}
    102     geopoly              => {Enable the GEOPOLY extension}
    103     rtree                => {Enable the RTREE extension}
    104     session              => {Enable the SESSION extension}
    105     all=1                => {Disable $::sqlite__Config(all-flag-enables)}
    106     with-icu-ldflags:LDFLAGS
    107       => {Enable SQLITE_ENABLE_ICU and add the given linker flags for the
    108           ICU libraries. e.g. on Ubuntu systems, try '-licui18n -licuuc -licudata'.}
    109     with-icu-cflags:CFLAGS
    110       => {Apply extra CFLAGS/CPPFLAGS necessary for building with ICU.
    111           e.g. -I/usr/local/include}
    112     with-icu-config:=auto
    113       => {Enable SQLITE_ENABLE_ICU. Value must be one of: auto, pkg-config,
    114           /path/to/icu-config}
    115     icu-collations=0
    116       => {Enable SQLITE_ENABLE_ICU_COLLATIONS. Requires --with-icu-ldflags=...
    117           or --with-icu-config}
    118   }]
    119 }
    120 
    121 #
    122 # Gets called by tea-configure-core. Must perform any configuration
    123 # work needed for this extension.
    124 #
    125 proc teaish-configure {} {
    126   use teaish/feature
    127 
    128   if {[proj-opt-was-provided override-sqlite-version]} {
    129     teaish-pkginfo-set -version [opt-val override-sqlite-version]
    130     proj-warn "overriding sqlite version number:" [teaish-pkginfo-get -version]
    131   } elseif {[proj-opt-was-provided with-system-sqlite]
    132             && [opt-val with-system-sqlite] ne "0"} {
    133     proj-fatal "when using --with-system-sqlite also use" \
    134       "--override-sqlite-version to specify a library version number."
    135   }
    136 
    137   define CFLAGS [proj-get-env CFLAGS {-O2}]
    138   sqlite-munge-cflags
    139 
    140   #
    141   # Add feature flags from legacy configure.ac which are not covered by
    142   # --flags.
    143   #
    144   sqlite-add-feature-flag {
    145     -DSQLITE_3_SUFFIX_ONLY=1
    146     -DSQLITE_ENABLE_DESERIALIZE=1
    147     -DSQLITE_ENABLE_DBPAGE_VTAB=1
    148     -DSQLITE_ENABLE_BYTECODE_VTAB=1
    149     -DSQLITE_ENABLE_DBSTAT_VTAB=1
    150   }
    151 
    152   if {[opt-bool with-system-sqlite]} {
    153     msg-result "Using system-level sqlite3."
    154     teaish-cflags-add -DUSE_SYSTEM_SQLITE
    155     teaish-ldflags-add -lsqlite3
    156   } elseif {$::sqlite__Config(is-canonical)} {
    157     teaish-cflags-add -I[teaish-get -dir]/..
    158   }
    159 
    160   teaish-check-librt
    161   teaish-check-libz
    162   sqlite-handle-threadsafe
    163   sqlite-handle-tempstore
    164   sqlite-handle-load-extension
    165   sqlite-handle-math
    166   sqlite-handle-icu
    167 
    168   sqlite-handle-common-feature-flags; # must be late in the process
    169 }; # teaish-configure
    170 
    171 define OPT_FEATURE_FLAGS {} ; # -DSQLITE_OMIT/ENABLE flags.
    172 #
    173 # Adds $args, if not empty, to OPT_FEATURE_FLAGS. This is intended only for holding
    174 # -DSQLITE_ENABLE/OMIT/... flags, but that is not enforced here.
    175 proc sqlite-add-feature-flag {args} {
    176   if {"" ne $args} {
    177     define-append OPT_FEATURE_FLAGS {*}$args
    178   }
    179 }
    180 
    181 #
    182 # Check for log(3) in libm and die with an error if it is not
    183 # found. $featureName should be the feature name which requires that
    184 # function (it's used only in error messages). defines LDFLAGS_MATH to
    185 # the required linker flags (which may be empty even if the math APIs
    186 # are found, depending on the OS).
    187 proc sqlite-affirm-have-math {featureName} {
    188   if {"" eq [get-define LDFLAGS_MATH ""]} {
    189     if {![msg-quiet proj-check-function-in-lib log m]} {
    190       user-error "Missing math APIs for $featureName"
    191     }
    192     set lfl [get-define lib_log ""]
    193     undefine lib_log
    194     if {"" ne $lfl} {
    195       user-notice "Forcing requirement of $lfl for $featureName"
    196     }
    197     define LDFLAGS_MATH $lfl
    198     teaish-ldflags-prepend $lfl
    199   }
    200 }
    201 
    202 #
    203 # Handle various SQLITE_ENABLE/OMIT_... feature flags.
    204 proc sqlite-handle-common-feature-flags {} {
    205   msg-result "Feature flags..."
    206   if {![opt-bool all]} {
    207     # Special handling for --disable-all
    208     foreach flag $::sqlite__Config(all-flag-enables) {
    209       if {![proj-opt-was-provided $flag]} {
    210         proj-opt-set $flag 0
    211       }
    212     }
    213   }
    214   foreach {boolFlag featureFlag ifSetEvalThis} [proj-strip-hash-comments {
    215     all         {} {
    216       # The 'all' option must be first in this list.  This impl makes
    217       # an effort to only apply flags which the user did not already
    218       # apply, so that combinations like (--all --disable-geopoly)
    219       # will indeed disable geopoly. There are corner cases where
    220       # flags which depend on each other will behave in non-intuitive
    221       # ways:
    222       #
    223       # --all --disable-rtree
    224       #
    225       # Will NOT disable geopoly, though geopoly depends on rtree.
    226       # The --geopoly flag, though, will automatically re-enable
    227       # --rtree, so --disable-rtree won't actually disable anything in
    228       # that case.
    229       foreach k $::sqlite__Config(all-flag-enables) {
    230         if {![proj-opt-was-provided $k]} {
    231           proj-opt-set $k 1
    232         }
    233       }
    234     }
    235     fts3         -DSQLITE_ENABLE_FTS3    {sqlite-affirm-have-math fts3}
    236     fts4         -DSQLITE_ENABLE_FTS4    {sqlite-affirm-have-math fts4}
    237     fts5         -DSQLITE_ENABLE_FTS5    {sqlite-affirm-have-math fts5}
    238     geopoly      -DSQLITE_ENABLE_GEOPOLY {proj-opt-set rtree}
    239     rtree        -DSQLITE_ENABLE_RTREE   {}
    240     session      {-DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK} {}
    241     update-limit -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT {}
    242     scanstatus     -DSQLITE_ENABLE_STMT_SCANSTATUS {}
    243   }] {
    244     if {$boolFlag ni $::autosetup(options)} {
    245       # Skip flags which are in the canonical build but not
    246       # the autoconf bundle.
    247       continue
    248     }
    249     proj-if-opt-truthy $boolFlag {
    250       sqlite-add-feature-flag $featureFlag
    251       if {0 != [eval $ifSetEvalThis] && "all" ne $boolFlag} {
    252         msg-result "  + $boolFlag"
    253       }
    254     } {
    255       if {"all" ne $boolFlag} {
    256         msg-result "  - $boolFlag"
    257       }
    258     }
    259   }
    260   #
    261   # Invert the above loop's logic for some SQLITE_OMIT_...  cases. If
    262   # config option $boolFlag is false, [sqlite-add-feature-flag
    263   # $featureFlag], where $featureFlag is intended to be
    264   # -DSQLITE_OMIT_...
    265   foreach {boolFlag featureFlag} {
    266     json        -DSQLITE_OMIT_JSON
    267   } {
    268     if {[proj-opt-truthy $boolFlag]} {
    269       msg-result "  + $boolFlag"
    270     } else {
    271       sqlite-add-feature-flag $featureFlag
    272       msg-result "  - $boolFlag"
    273     }
    274   }
    275 
    276   ##
    277   # Remove duplicates from the final feature flag sets and show them
    278   # to the user.
    279   set oFF [get-define OPT_FEATURE_FLAGS]
    280   if {"" ne $oFF} {
    281     define OPT_FEATURE_FLAGS [lsort -unique $oFF]
    282     msg-result "Library feature flags: [get-define OPT_FEATURE_FLAGS]"
    283   }
    284   if {[lsearch [get-define TARGET_DEBUG ""] -DSQLITE_DEBUG=1] > -1} {
    285     msg-result "Note: this is a debug build, so performance will suffer."
    286   }
    287   teaish-cflags-add -define OPT_FEATURE_FLAGS
    288 }; # sqlite-handle-common-feature-flags
    289 
    290 #
    291 # If --enable-threadsafe is set, this adds -DSQLITE_THREADSAFE=1 to
    292 # OPT_FEATURE_FLAGS and sets LDFLAGS_PTHREAD to the linker flags
    293 # needed for linking pthread (possibly an empty string). If
    294 # --enable-threadsafe is not set, adds -DSQLITE_THREADSAFE=0 to
    295 # OPT_FEATURE_FLAGS and sets LDFLAGS_PTHREAD to an empty string.
    296 #
    297 # It prepends the flags to the global LDFLAGS.
    298 proc sqlite-handle-threadsafe {} {
    299   msg-checking "Support threadsafe operation? "
    300   define LDFLAGS_PTHREAD ""
    301   set enable 0
    302   if {[proj-opt-was-provided threadsafe]} {
    303     proj-if-opt-truthy threadsafe {
    304       if {[proj-check-function-in-lib pthread_create pthread]
    305           && [proj-check-function-in-lib pthread_mutexattr_init pthread]} {
    306         incr enable
    307         set ldf [get-define lib_pthread_create]
    308         define LDFLAGS_PTHREAD $ldf
    309         teaish-ldflags-prepend $ldf
    310         undefine lib_pthread_create
    311         undefine lib_pthread_mutexattr_init
    312       } else {
    313         user-error "Missing required pthread libraries. Use --disable-threadsafe to disable this check."
    314       }
    315       # Recall that LDFLAGS_PTHREAD might be empty even if pthreads if
    316       # found because it's in -lc on some platforms.
    317     } {
    318       msg-result "Disabled using --disable-threadsafe"
    319     }
    320   } else {
    321     #
    322     # If user does not specify --[disable-]threadsafe then select a
    323     # default based on whether it looks like Tcl has threading
    324     # support.
    325     #
    326     catch {
    327       scan [exec echo {puts [tcl::pkgconfig get threaded]} | [get-define TCLSH_CMD]] \
    328         %d enable
    329     }
    330     if {$enable} {
    331       set flagName "--threadsafe"
    332       set lblAbled "enabled"
    333       msg-result yes
    334     } else {
    335       set flagName "--disable-threadsafe"
    336       set lblAbled "disabled"
    337       msg-result no
    338     }
    339     msg-result "Defaulting to ${flagName} because Tcl has threading ${lblAbled}."
    340     # ^^^ We (probably) don't need to link against -lpthread in the
    341     # is-enabled case. We might in the case of static linking. Unsure.
    342   }
    343   sqlite-add-feature-flag -DSQLITE_THREADSAFE=${enable}
    344   return $enable
    345 }
    346 
    347 #
    348 # Handles the --enable-load-extension flag. Returns 1 if the support
    349 # is enabled, else 0. If support for that feature is not found, a
    350 # fatal error is triggered if --enable-load-extension is explicitly
    351 # provided, else a loud warning is instead emitted. If
    352 # --disable-load-extension is used, no check is performed.
    353 #
    354 # Makes the following environment changes:
    355 #
    356 # - defines LDFLAGS_DLOPEN to any linker flags needed for this
    357 #   feature.  It may legally be empty on some systems where dlopen()
    358 #   is in libc.
    359 #
    360 # - If the feature is not available, adds
    361 #   -DSQLITE_OMIT_LOAD_EXTENSION=1 to the feature flags list.
    362 proc sqlite-handle-load-extension {} {
    363   define LDFLAGS_DLOPEN ""
    364   set found 0
    365   proj-if-opt-truthy load-extension {
    366     set found [proj-check-function-in-lib dlopen dl]
    367     if {$found} {
    368       set ldf [get-define lib_dlopen]
    369       define LDFLAGS_DLOPEN $ldf
    370       teaish-ldflags-prepend $ldf
    371       undefine lib_dlopen
    372     } else {
    373       if {[proj-opt-was-provided load-extension]} {
    374         # Explicit --enable-load-extension: fail if not found
    375         proj-indented-notice -error {
    376           --enable-load-extension was provided but dlopen()
    377           not found. Use --disable-load-extension to bypass this
    378           check.
    379         }
    380       } else {
    381         # It was implicitly enabled: warn if not found
    382         proj-indented-notice {
    383           WARNING: dlopen() not found, so loadable module support will
    384           be disabled. Use --disable-load-extension to bypass this
    385           check.
    386         }
    387       }
    388     }
    389   }
    390   if {$found} {
    391     msg-result "Loadable extension support enabled."
    392   } else {
    393     msg-result "Disabling loadable extension support. Use --enable-load-extension to enable them."
    394     sqlite-add-feature-flag -DSQLITE_OMIT_LOAD_EXTENSION=1
    395   }
    396   return $found
    397 }
    398 
    399 #
    400 # ICU - International Components for Unicode
    401 #
    402 # Handles these flags:
    403 #
    404 #  --with-icu-ldflags=LDFLAGS
    405 #  --with-icu-cflags=CFLAGS
    406 #  --with-icu-config[=auto | pkg-config | /path/to/icu-config]
    407 #  --enable-icu-collations
    408 #
    409 # --with-icu-config values:
    410 #
    411 #   - auto: use the first one of (pkg-config, icu-config) found on the
    412 #     system.
    413 #   - pkg-config: use only pkg-config to determine flags
    414 #   - /path/to/icu-config: use that to determine flags
    415 #
    416 # If --with-icu-config is used as neither pkg-config nor icu-config
    417 # are found, fail fatally.
    418 #
    419 # If both --with-icu-ldflags and --with-icu-config are provided, they
    420 # are cumulative.  If neither are provided, icu-collations is not
    421 # honored and a warning is emitted if it is provided.
    422 #
    423 # Design note: though we could automatically enable ICU if the
    424 # icu-config binary or (pkg-config icu-io) are found, we specifically
    425 # do not. ICU is always an opt-in feature.
    426 proc sqlite-handle-icu {} {
    427   define LDFLAGS_LIBICU [join [opt-val with-icu-ldflags ""]]
    428   define CFLAGS_LIBICU [join [opt-val with-icu-cflags ""]]
    429   if {[proj-opt-was-provided with-icu-config]} {
    430     msg-result "Checking for ICU support..."
    431     set icuConfigBin [opt-val with-icu-config]
    432     set tryIcuConfigBin 1; # set to 0 if we end up using pkg-config
    433     if {$icuConfigBin in {auto pkg-config}} {
    434       uplevel 3 { use pkg-config }
    435       if {[pkg-config-init 0] && [pkg-config icu-io]} {
    436         # Maintenance reminder: historical docs say to use both of
    437         # (icu-io, icu-uc). icu-uc lacks a required lib and icu-io has
    438         # all of them on tested OSes.
    439         set tryIcuConfigBin 0
    440         define LDFLAGS_LIBICU [get-define PKG_ICU_IO_LDFLAGS]
    441         define-append LDFLAGS_LIBICU [get-define PKG_ICU_IO_LIBS]
    442         define CFLAGS_LIBICU [get-define PKG_ICU_IO_CFLAGS]
    443       } elseif {"pkg-config" eq $icuConfigBin} {
    444         proj-fatal "pkg-config cannot find package icu-io"
    445       } else {
    446         proj-assert {"auto" eq $icuConfigBin}
    447       }
    448     }
    449     if {$tryIcuConfigBin} {
    450       if {"auto" eq $icuConfigBin} {
    451         set icuConfigBin [proj-first-bin-of \
    452                             /usr/local/bin/icu-config \
    453                             /usr/bin/icu-config]
    454         if {"" eq $icuConfigBin} {
    455           proj-indented-notice -error {
    456             --with-icu-config=auto cannot find (pkg-config icu-io) or icu-config binary.
    457             On Ubuntu-like systems try:
    458             --with-icu-ldflags='-licui18n -licuuc -licudata'
    459           }
    460         }
    461       }
    462       if {[file-isexec $icuConfigBin]} {
    463         set x [exec $icuConfigBin --ldflags]
    464         if {"" eq $x} {
    465           proj-indented-notice -error \
    466             [subst {
    467               $icuConfigBin --ldflags returned no data.
    468               On Ubuntu-like systems try:
    469               --with-icu-ldflags='-licui18n -licuuc -licudata'
    470             }]
    471         }
    472         define-append LDFLAGS_LIBICU $x
    473         set x [exec $icuConfigBin --cppflags]
    474         define-append CFLAGS_LIBICU $x
    475       } else {
    476         proj-fatal "--with-icu-config=$icuConfigBin does not refer to an executable"
    477       }
    478     }
    479   }
    480   set ldflags [define LDFLAGS_LIBICU [string trim [get-define LDFLAGS_LIBICU]]]
    481   set cflags [define CFLAGS_LIBICU [string trim [get-define CFLAGS_LIBICU]]]
    482   if {"" ne $ldflags} {
    483     sqlite-add-feature-flag -DSQLITE_ENABLE_ICU
    484     msg-result "Enabling ICU support with flags: $ldflags $cflags"
    485     if {[opt-bool icu-collations]} {
    486       msg-result "Enabling ICU collations."
    487       sqlite-add-feature-flag -DSQLITE_ENABLE_ICU_COLLATIONS
    488     }
    489     teaish-ldflags-prepend $ldflags
    490     teaish-cflags-add $cflags
    491   } elseif {[opt-bool icu-collations]} {
    492     proj-warn "ignoring --enable-icu-collations because neither --with-icu-ldflags nor --with-icu-config provided any linker flags"
    493   } else {
    494     msg-result "ICU support is disabled."
    495   }
    496 }; # sqlite-handle-icu
    497 
    498 
    499 #
    500 # Handles the --with-tempstore flag.
    501 #
    502 # The test fixture likes to set SQLITE_TEMP_STORE on its own, so do
    503 # not set that feature flag unless it was explicitly provided to the
    504 # configure script.
    505 proc sqlite-handle-tempstore {} {
    506   if {[proj-opt-was-provided with-tempstore]} {
    507     set ts [opt-val with-tempstore no]
    508     set tsn 1
    509     msg-checking "Use an in-RAM database for temporary tables? "
    510     switch -exact -- $ts {
    511       never  { set tsn 0 }
    512       no     { set tsn 1 }
    513       yes    { set tsn 2 }
    514       always { set tsn 3 }
    515       default {
    516         user-error "Invalid --with-tempstore value '$ts'. Use one of: never, no, yes, always"
    517       }
    518     }
    519     msg-result $ts
    520     sqlite-add-feature-flag -DSQLITE_TEMP_STORE=$tsn
    521   }
    522 }
    523 
    524 #
    525 # Handles the --enable-math flag.
    526 proc sqlite-handle-math {} {
    527   proj-if-opt-truthy math {
    528     if {![proj-check-function-in-lib ceil m]} {
    529       user-error "Cannot find libm functions. Use --disable-math to bypass this."
    530     }
    531     set lfl [get-define lib_ceil]
    532     undefine lib_ceil
    533     define LDFLAGS_MATH $lfl
    534     teaish-ldflags-prepend $lfl
    535     sqlite-add-feature-flag -DSQLITE_ENABLE_MATH_FUNCTIONS
    536     msg-result "Enabling math SQL functions"
    537   } {
    538     define LDFLAGS_MATH ""
    539     msg-result "Disabling math SQL functions"
    540   }
    541 }
    542 
    543 #
    544 # Move -DSQLITE_OMIT... and -DSQLITE_ENABLE... flags from CFLAGS and
    545 # CPPFLAGS to OPT_FEATURE_FLAGS and remove them from BUILD_CFLAGS.
    546 proc sqlite-munge-cflags {} {
    547   # Move CFLAGS and CPPFLAGS entries matching -DSQLITE_OMIT* and
    548   # -DSQLITE_ENABLE* to OPT_FEATURE_FLAGS. This behavior is derived
    549   # from the pre-3.48 build.
    550   #
    551   # If any configure flags for features are in conflict with
    552   # CFLAGS/CPPFLAGS-specified feature flags, all bets are off.  There
    553   # are no guarantees about which one will take precedence.
    554   foreach flagDef {CFLAGS CPPFLAGS} {
    555     set tmp ""
    556     foreach cf [get-define $flagDef ""] {
    557       switch -glob -- $cf {
    558         -DSQLITE_OMIT* -
    559         -DSQLITE_ENABLE* {
    560           sqlite-add-feature-flag $cf
    561         }
    562         default {
    563           lappend tmp $cf
    564         }
    565       }
    566     }
    567     define $flagDef $tmp
    568   }
    569 }
    570