# File convertdb.rb, line 75
def main
        $stderr.sync = $stdout.sync = true
        header "WordNet Lexicon Converter"
        errorLimit = 0

        ARGV.options {|oparser|
                oparser.banner = "Usage: #{File::basename($0)} -dv\n"

                # Debugging on/off
                oparser.on( "--debug", "-d", TrueClass, "Turn debugging on" ) {
                        $DEBUG = true
                        debugMsg "Turned debugging on."
                }

                # Verbose
                oparser.on( "--verbose", "-v", TrueClass, "Verbose progress messages" ) {
                        $VERBOSE = true
                        debugMsg "Turned verbose on."
                }

                # Error-limit
                oparser.on( "--error-limit=COUNT", "-eCOUNT", Integer,
                        "Error limit -- quit after COUNT errors" ) {|arg|
                        errorLimit = arg.to_i
                        debugMsg "Set error limit to #{errorLimit}"
                }

                # Handle the 'help' option
                oparser.on( "--help", "-h", "Display this text." ) {
                        $stderr.puts oparser
                        exit!(0)
                }

                oparser.parse!
        }

        # Make sure the user knows what they're in for
        message "This program will convert WordNet data files into databases\n"\
                "used by Ruby-WordNet. This will not affect existing WordNet files,\n"\
                "but will require up to 40Mb of disk space.\n"
        exit unless /^y/i =~ promptWithDefault("Continue?", "y")

        # Open the database and check to be sure it's empty. Confirm overwrite if
        # not. Checkpoint and set up logging proc if debugging.
        if File::exists?( WordNet::Lexicon::DbFile )
                message ">>> Warning: Existing data in the Ruby-WordNet databases\n"\
                        "will be overwritten.\n"
                abort( "user cancelled." ) unless 
                        /^y/i =~ promptWithDefault( "Continue?", "n" )
                FileUtils::rm_rf( WordNet::Lexicon::DbFile )
        end

        # Find the source data files
        if ARGV.empty?
                message "Where can I find the WordNet data files?\n"
                datadir = promptWithDefault( "Data directory", "/usr/local/WordNet-2.0/dict" )
        else
                datadir = ARGV.shift
        end

        abort( "Directory '#{datadir}' does not exist" ) unless File::exists?( datadir )
        abort( "'#{datadir}' is not a directory" ) unless File::directory?( datadir )
        testfile = File::join(datadir, "data.noun")
        abort( "'#{datadir}' doesn't seem to contain the necessary files.") unless
                File::exists?( testfile )

        # Open the lexicon, which creates a new database under lib/wordnet/lexicon.
        lexicon = WordNet::Lexicon::new

        # Process each fileset
        [        # Fileset,  name,    database handle, processor
                Fileset::new( IndexFiles, "index", lexicon.indexDb, method(:parseIndexLine) ),
                Fileset::new( MorphFiles, "morph", lexicon.morphDb, method(:parseMorphLine) ),
                Fileset::new( DataFiles,  "data",  lexicon.dataDb,  method(:parseSynsetLine) ),
        ].each {|set|
                message "Converting %s files...\n" % set.name
                set.db.truncate

                # Process each file in the set with the appropriate processor method and
                # insert results into the corresponding table.
                set.files.each {|file,pos|
                        message "    #{file}..."

                        filepath = File::join( datadir, file )
                        if !File::exists?( filepath )
                                message "missing: skipped\n"
                                next
                        end

                        txn, dbh = lexicon.env.txn_begin( 0, set.db )
                        entries = lineNumber = errors = 0
                        File::readlines( filepath ).each {|line|
                                lineNumber += 1
                                next if /^\s/ =~ line

                                key, value = set.processor.call( line.chomp, lineNumber, pos )
                                unless key
                                        errors += 1
                                        if errorLimit.nonzero? && errors >= errorLimit
                                                abort( "Too many errors" )
                                        end
                                end

                                dbh[ key ] = value
                                entries += 1
                                print "%d%s" % [ entries, "\x08" * entries.to_s.length ]

                                # Commit and start a new transaction every 1000 records
                                if (entries % CommitThreshold).nonzero?
                                        txn.commit( BDB::TXN_NOSYNC )
                                        txn, dbh = lexicon.env.txn_begin( 0, set.db )
                                end
                        }
                        message "committing..."
                        txn.commit( BDB::TXN_SYNC )
                        message "done (%d entries, %d errors).\n" %
                                [ entries, errors ]
                }

                message "Checkpointing DB and cleaning logs..."
                lexicon.checkpoint
                lexicon.cleanLogs
                puts "done."
        }

        message "done.\n\n"
end