/* This file is part of BOP. Copyright (C) 2004 Patrick Davalan This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA The GNU General Public License text is also available at http://www.gnu.org/ or on the Copyright holder web site : http://patrick.davalan.free.fr/gnu-gpl.html */ #define DEBUG 0 #include <sys/times.h> //FIXME comment the line below //#define HAVE_RANDOM // change the include to #include <bop.2/bop.h> #include "bop.h" typedef struct { BophHandle * hash ; // hash to store lines unsigned long lineNum ; // line number to make all lines different } LoadData ; static int load( void * data, char * line, unsigned int length) { #define loadData ( (LoadData *) data ) // this function is called for each input line. // put it in the hash size_t allocSize ; char * hashRecord ; BophEntry * entry ; // stored hash entry unsigned long * pNum ; bopdEnter( ) ; bopdTrace(" line <%s> length=%u\n", line, length ) ; // prepend a line number to make all lines different loadData->lineNum += 1 ; allocSize = length + 2 + sizeof(unsigned long) ; #ifndef HAVE_ALLOCA bopdTrace( "use bopmMalloc size=%u\n", allocSize ) ; hashRecord = bopmMalloc( allocSize) ; #else bopdTrace( "use alloca size=%u\n", allocSize ) ; hashRecord = alloca( allocSize) ; #endif pNum = ( unsigned long * ) hashRecord ; * pNum = loadData->lineNum ; memcpy( hashRecord + sizeof(unsigned long), line, length ) ; * (hashRecord + allocSize - 2) = '\n' ; * (hashRecord + allocSize - 1) = 0 ; // put it in hash entry = bophPut( loadData->hash, hashRecord, allocSize, NULL, 0, BOPH_PUT ) ; if ( entry == NULL ) { bopxAbort( "Cannot store in hash" ) ; } #ifndef HAVE_ALLOCA // the record has been copied in the hash, free it bopmFree( hashRecord ) ; #endif #undef loadData bopdReturn( false ) ; return( false ) ; } static int unload( void * data, BophEntry * entry ) { // this function is called for each hash entry. // output the line char * line ; bopdEnter( ) ; // do not output the line number line = ( (char *)bophGetKey( entry ) ) + sizeof(unsigned long) ; fputs( line, (FILE *)data ) ; bopdTrace( "fputs <%s>\n", line ) ; bopdReturn( false ) ; return( false ) ; } int main( int argc, char * argv[] ) { BophHandle * hash ; char * fileName ; unsigned int hashSize ; LoadData loadData ; bopmTrace ( ) ; bopdEnter( ) ; // get the filename argument if ( argc < 2 ) { fprintf( stderr, "bopshuffle: argument expected\n" ) ; fprintf( stderr, "usage: bopshuffle filename\n" ) ; exit( EXIT_FAILURE ) ; } fileName = argv[1] ; // find a "random" hash size // que vient faire Marignan dans cette histoire ? hashSize = ( bopxRandom( ) % 8191 ) + 1515 ; // create a hash bopdTrace( "hash size %u\n", hashSize ) ; hash = bophNew( NULL, "shuffle hash", hashSize, NULL, NULL ) ; // load the file in the hash loadData.hash = hash ; loadData.lineNum = 0 ; bopxScanLines( &loadData, fileName, load ) ; // unload the hash on stdout bophScan( stdout, hash, unload ) ; // unusefully free the hash object bophDelete ( NULL, hash ) ; bopmMem( ) ; bopdReturn( EXIT_SUCCESS ) ; return( EXIT_SUCCESS ) ; }