/* * Copyright 1997 Perforce Software. All rights reserved. * * This file is part of Perforce - the FAST SCM System. * * Diff code written by James Strickland, May 1997. */ #include <stdlib.h> // for realloc() # define NEED_TYPES #include <stdhdrs.h> #include <error.h> #include <strbuf.h> #include <readfile.h> #include "diff.h" #include "diffsp.h" #include "diffsr.h" /* * Sequence - a file as an abstract sequence of elements * * Sequence just manages the element list. The Sequencers do * the actual file reading/hashing/comparing. */ /* * Sequence::Sequence() - open file and hash lines */ Sequence::Sequence( FileSys *f, const DiffFlags &flags, Error *e ) { line = 0; lineCount = 0; lineMax = 0; reallocCount = 0; sequencer = 0; readfile = new ReadFile; // Build list of line hashes. switch( flags.sequence ) { case DiffFlags::Line: sequencer = new LineReader; break; case DiffFlags::Word: sequencer = new WordReader; break; case DiffFlags::WClass: sequencer = new WClassReader; break; case DiffFlags::DashL: sequencer = new DifflReader; break; case DiffFlags::DashB: sequencer = new DiffbReader; break; case DiffFlags::DashW: sequencer = new DiffwReader; break; } // We open, ~Sequence() closes. sequencer->A = this; sequencer->src = readfile; readfile->Open( f, e ); if( e->Test() ) return; // allocate initial space GrowLineBuf( e ); if( e->Test() ) return; line[0].offset = 0 ; line[1].offset = 0 ; // Load lines sequencer->Load( e ); } /* * Sequence::~Sequence() - close file */ Sequence::~Sequence() { delete sequencer; readfile->Close(); delete readfile; if( line ) free( line ); } /* * Sequence::StoreLine() - add hash/offset to list */ void Sequence::StoreLine( HashVal HashValue, Error *e ) { // we need to store indices from 0..n+1 // give us more space! if( lineCount+1 >= lineMax ) GrowLineBuf( e ); if( e->Test() ) return; line[ lineCount ].hash = HashValue; line[ lineCount+1 ].offset = readfile->Tell(); ++lineCount; } /* * Sequence::GrowLineBuf() - grow hash/offset list table */ void Sequence::GrowLineBuf( Error *e ) { LineNo CharsPerLine; /* * We try to gues right. * * First: size in bytes/"guess" of # of chars per line * Second: size in bytes/average # of chars per line * After that: just double each time */ switch( reallocCount++ ) { case 0: // allocate initial space: 32 = numCharsPerLine guess lineMax = 200 + readfile->Size() / 32; break; case 1: // reallocate based on actual number of characters per line CharsPerLine = Off( lineCount ) / lineCount; lineMax = readfile->Size() / 10 * 13 / CharsPerLine; break; default: lineMax *= 2; break; } /* SunOS 4.1.4 didn't like to realloc 0. */ VarInfo *l; if( line ) l = (VarInfo *)realloc( line, (sizeof(VarInfo)) * lineMax ); else l = (VarInfo *)malloc( (sizeof(VarInfo)) * lineMax ); if( l ) line = l; if( !l ) e->Sys( "malloc", "out of memory" ); } /* * Sequence::CopyLines() - copy given lines into buffer */ int Sequence::CopyLines( LineNo &l, LineNo m, char *buf, int len, LineType lineType ) { // Don't go past the end of the file! if( Lines() < m ) m = Lines(); // Copy what we can len = readfile->Textcpy( buf, len, LengthLeft( m - 1 ), lineType ); // Did we finish? if( !LengthLeft( m - 1 ) ) l = m; return len; } /* * Sequence::Dump() - copy given lines into FILE * returns true if the last line ends with a newline, * flase if not. */ bool Sequence::Dump( FILE *out, LineNo l, LineNo m, LineType lineType ) { int len; int llen = 0; char buf[ 1024 ]; while( len = CopyLines( l, m, buf, sizeof( buf ), lineType ) ) { fwrite( buf, 1, len, out ); llen = len; } return( ( llen > 0 && buf[ llen - 1 ] != '\n' ) ? false : true ); }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 14945 | Newtopian |
Merging //guest/perforce_software/p4/... to //guest/Newtopian/p4/... |
||
//guest/perforce_software/p4/2014.1/diff/diffsp.cc | |||||
#1 | 12188 | Matt Attaway | Move 'main' p4 into a release specific directory in prep for new releases | ||
//guest/perforce_software/p4/diff/diffsp.cc | |||||
#1 | 9129 | Matt Attaway | Initial commit of the 2014.1 p4/p4api source code |