+++ /dev/null
-/*---------------------------------------------------------------------\
-| ____ _ __ __ ___ |
-| |__ / \ / / . \ . \ |
-| / / \ V /| _/ _/ |
-| / /__ | | | | | | |
-| /_____||_| |_| |_| |
-| |
-\---------------------------------------------------------------------*/
-/** \file zypp/target/rpm/BinHeaderCache.cc
- *
-*/
-#include "librpm.h"
-
-#include <iostream>
-
-#include "zypp/base/Logger.h"
-#include "zypp/Date.h"
-#include "zypp/PathInfo.h"
-#include "zypp/base/String.h"
-
-#include "zypp/target/rpm/BinHeader.h"
-#include "zypp/target/rpm/BinHeaderCache.h"
-
-using namespace std;
-
-namespace zypp {
- namespace target {
- namespace rpm {
-
- ///////////////////////////////////////////////////////////////////
- //
- // CLASS NAME : BinHeaderCache::Cache
- /**
- *
- **/
- class BinHeaderCache::Cache {
-
- friend std::ostream & operator<<( std::ostream & str, const Cache & obj );
-
- Cache & operator=( const Cache & );
- Cache ( const Cache & );
-
- private:
-
- FD_t fd;
- pos _fdpos; // keep track of filepos for tell()
-
- public:
-
- Cache() : fd( 0 ), _fdpos( ~0 ) {}
- ~Cache() { close(); }
-
- public:
-
- bool open( const Pathname & file_r );
-
- bool isOpen() const { return( fd != 0 ); }
-
- void close();
-
- public:
-
- pos tell() const;
-
- pos seek( const pos pos_r );
-
- unsigned readData( void * buf_r, unsigned count_r );
-
- Header readHeader( bool magicp = true );
- };
-
- ///////////////////////////////////////////////////////////////////
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : BinHeaderCache::Cache::open
- // METHOD TYPE : bool
- //
- bool BinHeaderCache::Cache::open( const Pathname & file_r )
- {
- close();
-
- switch ( zipType( file_r ) ) {
- case filesystem::ZT_NONE:
- {
- fd = ::Fopen( file_r.asString().c_str(), "r.fdio" );
- DBG << "PLAIN: open 'r.fdio' " << fd << endl;
- }
- break;
- case filesystem::ZT_GZ:
- {
- fd = ::Fopen( file_r.asString().c_str(), "r.gzdio" );
- DBG << "GZIP: open 'r.gzdio' " << fd << endl;
- }
- break;
- case filesystem::ZT_BZ2:
- {
- ERR << "BZIP2 is not supported: " << file_r << endl;
- #warning Check BZIP2 support
- break;
- fd = ::Fopen( file_r.asString().c_str(), "r.bzdio" );
- DBG << "BZIP2: open 'r.bzdio' " << fd << endl;
- }
- break;
- }
-
- if ( fd == 0 || ::Ferror(fd) ) {
- ERR << "Can't open cache for reading: " << file_r << " (" << ::Fstrerror(fd) << ")" << endl;
- close();
- return false;
- }
- _fdpos = 0;
- return true;
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : BinHeaderCache::Cache::close
- // METHOD TYPE : void
- //
- void BinHeaderCache::Cache::close()
- {
- if ( fd ) {
- ::Fclose( fd );
- fd = 0;
- _fdpos = ~0;
- }
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : BinHeaderCache::Cache::tell
- // METHOD TYPE : pos
- //
-
- extern "C" {
- typedef struct X_FDSTACK_s {
- FDIO_t io;
- void * fp;
- int fdno;
- } XFDSTACK_t;
-
- struct X_FD_s {
- int nrefs;
- int flags;
- int magic;
- #define XFDMAGIC 0x04463138
- int nfps;
- XFDSTACK_t fps[8];
- };
- }
-
- BinHeaderCache::pos BinHeaderCache::Cache::tell() const
- {
- pos rc = npos;
-
- struct X_FD_s * xfd = (struct X_FD_s*)fd;
-
- if ( !xfd || xfd->magic != XFDMAGIC) {
- INT << "magic(" << XFDMAGIC << ") failed: " << xfd->magic << endl;
- return rc;
- }
-
- return _fdpos;
- #if 0
- if ( xfd->fps[xfd->nfps].io == fpio ) {
- FILE * fp = (FILE *)xfd->fps[xfd->nfps].fp;
- rc = ftell(fp);
- }
-
- if ( rc == npos )
- WAR << "Can't tell:" << ::Ferror(fd) << " (" << ::Fstrerror(fd) << ")" << endl;
- return rc;
- #endif
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : BinHeaderCache::Cache::seek
- // METHOD TYPE : pos
- //
- BinHeaderCache::pos BinHeaderCache::Cache::seek( const pos pos_r )
- {
- pos rc = npos;
-
- if ( pos_r != npos ) {
- ::Fseek( fd, pos_r, SEEK_SET );
- _fdpos = pos_r;
- if ( tell() == pos_r )
- rc = pos_r;
- } else {
- INT << "Attempt to seek to pos -1" << endl;
- }
-
- if ( rc == npos )
- WAR << "Can't seek to " << pos_r << ":" << ::Ferror(fd) << " (" << ::Fstrerror(fd) << ")" << endl;
- return rc;
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : BinHeaderCache::Cache::readData
- // METHOD TYPE : unsigned
- //
- unsigned BinHeaderCache::Cache::readData( void * buf_r, unsigned count_r )
- {
- if ( !buf_r ) {
- INT << "Attempt to fill NULL buffer" << endl;
- return 0;
- }
- if ( !count_r ) {
- return 0;
- }
-
- unsigned got = ::Fread( buf_r, sizeof(char), count_r, fd );
- _fdpos += got;
- if ( got != count_r ) {
- if ( got || ::Ferror(fd) ) {
- ERR << "Error reading " << count_r << " byte (" << ::Fstrerror(fd) << ")" << endl;
- } // else EOF?
- return 0;
- }
- return count_r;
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : BinHeaderCache::Cache::readHeader
- // METHOD TYPE : Header
- //
-
- extern "C" {
- #include <netinet/in.h>
- // from rpm: lib/header.c
- struct XXentryInfo {
- int_32 tag;
- int_32 type;
- int_32 offset; /* Offset from beginning of data segment,
- only defined on disk */
- int_32 count;
- };
- }
-
- Header BinHeaderCache::Cache::readHeader( bool magicp )
- {
- static const int_32 rpm_header_magic = 0x01e8ad8e;
-
- int_32 block[4];
- int_32 il, dl;
- unsigned totalSize = 0;
-
- unsigned count = (magicp ? 4 : 2) * sizeof(int_32);
- if ( readData( block, count ) != count ) {
- ERR << "Error reading header info (" << ::Fstrerror(fd) << ")" << endl;
- return 0;
- }
-
- count = 0;
-
- if ( magicp ) {
- if ( block[count] != rpm_header_magic ) {
- ERR << "Error bad header magic " << str::hexstring( block[count] )
- << " (" << str::hexstring( rpm_header_magic ) << ")" << endl;
- return 0;
- }
- count += 2;
- }
-
- il = ntohl( block[count++] );
- dl = ntohl( block[count++] );
-
- totalSize = (2*sizeof(int_32)) + (il * sizeof(struct XXentryInfo)) + dl;
- if (totalSize > (32*1024*1024)) {
- ERR << "Error header ecxeeds 32Mb limit (" << totalSize << ")" << endl;
- return NULL;
- }
-
- char * data = new char[totalSize];
- int_32 * p = (int_32 *)data;
- Header h = 0;
-
- *p++ = htonl(il);
- *p++ = htonl(dl);
- totalSize -= (2*sizeof(int_32));
-
- if ( readData( p, totalSize ) != totalSize ) {
- ERR << "Error reading header data (" << ::Fstrerror(fd) << ")" << endl;
- } else {
- h = ::headerCopyLoad( data );
- if ( !h ) {
- ERR << "Error loading header data" << endl;
- }
- }
-
- delete [] data;
-
- return h;
- }
-
-
- ///////////////////////////////////////////////////////////////////
- //
- // CLASS NAME : BinHeaderCache
- //
- ///////////////////////////////////////////////////////////////////
-
- const unsigned BinHeaderCache::BHC_MAGIC_SZE( 64 );
-
- const BinHeaderCache::pos BinHeaderCache::npos( BinHeaderCache::pos(-1) );
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : BinHeaderCache::BinHeaderCache
- // METHOD TYPE : Constructor
- //
- BinHeaderCache::BinHeaderCache( const Pathname & cache_r )
- : _c( * new Cache )
- , _cpath( cache_r )
- , _cdate( 0 )
- , _cheaderStart( npos )
- {
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : BinHeaderCache::~BinHeaderCache
- // METHOD TYPE : Destructor
- //
- BinHeaderCache::~BinHeaderCache()
- {
- delete &_c;
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : BinHeaderCache::_cReadMagic
- // METHOD TYPE : int
- //
- // [string\0][string\0][\0padded]
- //
- int BinHeaderCache::_cReadMagic()
- {
- char magic[BHC_MAGIC_SZE+1];
- memset( magic, 0, BHC_MAGIC_SZE+1 );
-
- if ( _c.readData( magic, BHC_MAGIC_SZE ) != BHC_MAGIC_SZE ) {
- ERR << "Error reading magic of cache file " << _cpath << endl;
- return -1;
- }
-
- _cmagic = magic;
- if ( _cmagic.size() < BHC_MAGIC_SZE ) {
- _cdate = strtoul( magic+_cmagic.size()+1, 0, 10 );
- if ( _cdate ) {
- _cheaderStart = BHC_MAGIC_SZE;
- return 0;
- }
- }
-
- ERR << "No magic in cache file " << _cpath << endl;
- return -2;
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : BinHeaderCache::open
- // METHOD TYPE : bool
- //
- bool BinHeaderCache::open()
- {
- if ( _c.isOpen() )
- return true;
-
- if ( !_c.open( _cpath ) ) {
- close();
- return false;
- }
-
- if ( _cReadMagic() != 0 ) {
- close();
- return false;
- }
-
- if ( !magicOk() ) {
- ERR << "Bad magic in cache file " << _cpath << endl;
- close();
- return false;
- }
-
- return true;
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : BinHeaderCache::isOpen
- // METHOD TYPE : bool
- //
- bool BinHeaderCache::isOpen() const
- {
- return _c.isOpen();
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : BinHeaderCache::close
- // METHOD TYPE : void
- //
- void BinHeaderCache::close()
- {
- _cmagic = "";
- _cdate = 0;
- _cheaderStart = npos;
- _c.close();
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : BinHeaderCache::tell
- // METHOD TYPE : BinHeaderCache::pos
- //
- BinHeaderCache::pos BinHeaderCache::tell() const
- {
- return _c.tell();
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : BinHeaderCache::seek
- // METHOD TYPE : BinHeaderCache::pos
- //
- BinHeaderCache::pos BinHeaderCache::seek( const pos pos_r )
- {
- return _c.seek( pos_r );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : BinHeaderCache::readData
- // METHOD TYPE : unsigned
- //
- unsigned BinHeaderCache::readData( void * buf_r, unsigned count_r )
- {
- return _c.readData( buf_r, count_r );
- }
-
- ///////////////////////////////////////////////////////////////////
- //
- //
- // METHOD NAME : BinHeaderCache::readHeader
- // METHOD TYPE : BinHeaderPtr
- //
- BinHeader::Ptr BinHeaderCache::readHeader( bool magicp )
- {
- Header h = _c.readHeader( magicp );
- if ( !h )
- return 0;
- return new BinHeader( h );
- }
-
- /******************************************************************
- **
- **
- ** FUNCTION NAME : operator<<
- ** FUNCTION TYPE : ostream &
- */
- ostream & operator<<( ostream & str, const BinHeaderCache & obj )
- {
- str << "BinHeaderCache@" << (void *)&obj;
- if ( obj.isOpen() ) {
- str << '(' << obj._cmagic << '|' << Date(obj._cdate) << "|at " << obj._cheaderStart << ')';
- } else {
- str << "(closed)";
- }
- return str;
- }
-
- } // namespace rpm
- } // namespace target
-} // namespace zypp
+++ /dev/null
-/*---------------------------------------------------------------------\
-| ____ _ __ __ ___ |
-| |__ / \ / / . \ . \ |
-| / / \ V /| _/ _/ |
-| / /__ | | | | | | |
-| /_____||_| |_| |_| |
-| |
-\---------------------------------------------------------------------*/
-/** \file zypp/target/rpm/BinHeaderCache.h
- *
-*/
-#ifndef ZYPP_TARGET_BINHEADERCACHE_H
-#define ZYPP_TARGET_BINHEADERCACHE_H
-
-#include <iosfwd>
-
-#include "zypp/Pathname.h"
-
-#include "zypp/target/rpm/BinHeader.h"
-
-namespace zypp {
- namespace target {
- namespace rpm {
-
- ///////////////////////////////////////////////////////////////////
- //
- // CLASS NAME : BinHeaderCache
- /**
- *
- **/
- class BinHeaderCache {
-
- friend std::ostream & operator<<( std::ostream & str, const BinHeaderCache & obj );
-
- BinHeaderCache & operator=( const BinHeaderCache & );
- BinHeaderCache ( const BinHeaderCache & );
-
- public:
-
- typedef unsigned pos;
-
- static const pos npos;
-
- private:
-
- static const unsigned BHC_MAGIC_SZE;
-
- class Cache;
-
- Cache & _c;
-
- private:
-
- int _cReadMagic();
-
- protected:
-
- Pathname _cpath;
-
- protected:
-
- std::string _cmagic;
-
- time_t _cdate;
-
- pos _cheaderStart;
-
- protected:
-
- virtual bool magicOk() { return _cmagic.empty(); }
-
- public:
-
- BinHeaderCache( const Pathname & cache_r );
-
- virtual ~BinHeaderCache();
-
- public:
-
- bool open();
-
- void close();
-
- bool isOpen() const;
-
- const Pathname & cpath() const { return _cpath; }
-
- const std::string & cmagic() const { return _cmagic; }
-
- time_t cdate() const { return _cdate; }
-
- pos tell() const;
-
- pos seek( const pos pos_r );
-
- unsigned readData( void * buf_r, unsigned count_r );
-
- BinHeader::Ptr readHeader( bool magicp = true );
- };
-
- ///////////////////////////////////////////////////////////////////
-
- } // namespace rpm
- } // namespace target
-} // namespace zypp
-
-#endif // ZYPP_TARGET_BINHEADERCACHE_H
+++ /dev/null
-/*---------------------------------------------------------------------\
-| ____ _ __ __ ___ |
-| |__ / \ / / . \ . \ |
-| / / \ V /| _/ _/ |
-| / /__ | | | | | | |
-| /_____||_| |_| |_| |
-| |
-\---------------------------------------------------------------------*/
-/** \file zypp/target/rpm/RpmHeaderCache.cc
- *
-*/
-
-#include <iostream>
-
-#include "zypp/base/Logger.h"
-
-#include "zypp/target/rpm/RpmHeaderCache.h"
-#include "zypp/target/rpm/RpmHeader.h"
-#include "librpm.h"
-#include "zypp/PathInfo.h"
-
-using namespace std;
-
-namespace zypp {
- namespace target {
- namespace rpm {
-
-///////////////////////////////////////////////////////////////////
-
-#warning add this function if needed
-#if 0
-const PkgNameEd & RpmHeaderCache::def_magic()
-{
- static PkgNameEd _def_magic( PkgName("YaST-PHC"), PkgEdition("1.0-0") );
- return _def_magic;
-}
-#endif
-
-///////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-//
-// METHOD NAME : RpmHeaderCache::RpmHeaderCache
-// METHOD TYPE : Constructor
-//
-RpmHeaderCache::RpmHeaderCache( const Pathname & cache_r )
- : BinHeaderCache( cache_r )
-{
-}
-
-///////////////////////////////////////////////////////////////////
-//
-//
-// METHOD NAME : RpmHeaderCache::~RpmHeaderCache
-// METHOD TYPE : Destructor
-//
-RpmHeaderCache::~RpmHeaderCache()
-{
-}
-
-#warning add this function if needed
-#if 0
-///////////////////////////////////////////////////////////////////
-//
-//
-// METHOD NAME : RpmHeaderCache::magicOk
-// METHOD TYPE : bool
-//
-bool RpmHeaderCache::magicOk()
-{
- PkgNameEd magic( PkgNameEd::fromString( _cmagic ) );
- if ( magic != def_magic() ) {
- ERR << "Found magic " << magic << ", expected " << def_magic() << endl;
- return false;
- }
- DBG << "Found magic " << magic << endl;
- return true;
-}
-#endif
-
-///////////////////////////////////////////////////////////////////
-#define RETURN_IF_CLOSED(R) if ( !isOpen() ) { ERR << "Cache not open: " << _cpath << endl; return R; }
-///////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-//
-// METHOD NAME : RpmHeaderCache::getFirst
-// METHOD TYPE : constRpmHeaderPtr
-//
-RpmHeader::constPtr RpmHeaderCache::getFirst( Pathname & citem_r, int & isSource_r, pos & at_r )
-{
- RETURN_IF_CLOSED( (RpmHeader*)0 );
-
- if ( seek( _cheaderStart ) == npos ) {
- ERR << "Can't seek to first header at " << _cheaderStart << endl;
- return (RpmHeader*)0;
- }
-
- return getNext( citem_r, isSource_r, at_r );
-}
-
-///////////////////////////////////////////////////////////////////
-//
-//
-// METHOD NAME : RpmHeaderCache::getNext
-// METHOD TYPE : constRpmHeaderPtr
-//
-RpmHeader::constPtr RpmHeaderCache::getNext( Pathname & citem_r, int & isSource_r, pos & at_r )
-{
- RETURN_IF_CLOSED( RpmHeader::constPtr() );
-
- static const unsigned sigsize = 8;
-
- char sig[sigsize+1];
- sig[sigsize] = '\0';
-
- unsigned count = readData( sig, sigsize );
- if ( count != sigsize ) {
- if ( count ) {
- ERR << "Error reading entry." << endl;
- } // else EOF?
- return (RpmHeader*)0;
- }
-
- if ( sig[0] != '@' || sig[sigsize-1] != '@' ) {
- ERR << "Invalid entry." << endl;
- return (RpmHeader*)0;
- }
-
- sig[sigsize-1] = '\0';
- count = atoi( &sig[1] );
-
- char citem[count+1];
- citem[count] = '\0';
-
- if ( readData( citem, count ) != count ) {
- ERR << "Error reading entry data." << endl;
- return (RpmHeader*)0;
- }
-
- isSource_r = ( citem[0] == 's' );
- citem_r = &citem[1];
- at_r = tell();
-
- return getAt( at_r );
-}
-
-
-///////////////////////////////////////////////////////////////////
-//
-//
-// METHOD NAME : RpmHeaderCache::getAt
-// METHOD TYPE : constRpmHeaderPtr
-//
-RpmHeader::constPtr RpmHeaderCache::getAt( pos at_r )
-{
- RETURN_IF_CLOSED( RpmHeader::constPtr() );
-
- if ( seek( at_r ) == npos ) {
- ERR << "Can't seek to header at " << at_r << endl;
- return (RpmHeader*)0;
- }
-
- BinHeader::Ptr bp = readHeader();
- if ( !bp ) {
- ERR << "Can't read header at " << at_r << endl;
- return (RpmHeader*)0;
- }
-
- return new RpmHeader( bp );
-}
-
-/******************************************************************
-**
-**
-** FUNCTION NAME : operator<<
-** FUNCTION TYPE : ostream &
-*/
-ostream & operator<<( ostream & str, const RpmHeaderCache & obj )
-{
- return str << "RpmHeaderCache@" << static_cast<const BinHeaderCache &>(obj);
-}
-
-///////////////////////////////////////////////////////////////////
-//
-#warning buildHeaderCache needs cleanup
-//
-///////////////////////////////////////////////////////////////////
-
-static const unsigned PHC_MAGIC_SZE = 64; // dont change!
-static const string PHC_MAGIC( "YaST-PHC-1.0-0" );
-
-/******************************************************************
-**
-**
-** FUNCTION NAME : phcAddMagic
-** FUNCTION TYPE : void
-*/
-void phcAddMagic( FD_t fd )
-{
- char magic[PHC_MAGIC_SZE];
- memset( magic, 0, PHC_MAGIC_SZE );
- strcpy( magic, PHC_MAGIC.c_str() );
- strcpy( magic+PHC_MAGIC.size()+1, str::numstring( Date::now() ).c_str() );
-
- ::Fwrite( magic, sizeof(char), PHC_MAGIC_SZE, fd );
-}
-
-/******************************************************************
-**
-**
-** FUNCTION NAME : phcAddHeader
-** FUNCTION TYPE : unsigned
-*/
-unsigned phcAddHeader( FD_t fd, Header h, const Pathname & citem_r, int isSource )
-{
- string entry = str::form( "%c%s", (isSource?'s':'b'), citem_r.asString().c_str() );
- entry = str::form( "@%6zu@%s", entry.size(), entry.c_str() );
-
- ::Fwrite( entry.c_str(), sizeof(char), entry.size(), fd );
- ::headerWrite( fd, h, HEADER_MAGIC_YES );
-
- return 1;
-}
-
-/******************************************************************
-**
-**
-** FUNCTION NAME : phcAddFile
-** FUNCTION TYPE : unsigned
-*/
-unsigned phcAddFile( FD_t fd, const PathInfo & cpath_r, const Pathname & citem_r )
-{
- FD_t pkg = ::Fopen( cpath_r.asString().c_str(), "r.ufdio" );
- if ( pkg == 0 || ::Ferror(pkg) ) {
- ERR << "Can't open file for reading: " << cpath_r << " (" << ::Fstrerror(pkg) << ")" << endl;
- if ( pkg )
- ::Fclose( pkg );
- return 0;
- }
-
- rpmts ts = rpmtsCreate();
- Header h = 0;
- int res = ::rpmReadPackageFile( ts, pkg, cpath_r.path().asString().c_str(), &h );
- ts = rpmtsFree(ts);
- ::Fclose( pkg );
-
- if ( ! h ) {
- WAR << "Error reading header from " << cpath_r << " error(" << res << ")" << endl;
- return 0;
- }
-
- RpmHeader::constPtr dummy( new RpmHeader( h ) ); // to handle header free
- headerFree( h ); // clear reference set in ReadPackageFile
- MIL << dummy << " for " << citem_r << endl;
-
- return phcAddHeader( fd, h, citem_r, dummy->isSrc() );
-}
-
-/******************************************************************
-**
-**
-** FUNCTION NAME : phcScanDir
-** FUNCTION TYPE : unsigned
-*/
-unsigned phcScanDir( FD_t fd, const PathInfo & cpath_r, const Pathname & prfx_r,
- const RpmHeaderCache::buildOpts & options_r )
-{
- DBG << "SCAN " << cpath_r << " (" << prfx_r << ")" << endl;
-
- list<string> retlist;
- int res = filesystem::readdir( retlist, cpath_r.path(), false );
- if ( res ) {
- ERR << "Error reading content of " << cpath_r << " (readdir " << res << ")" << endl;
- return 0;
- }
-
- unsigned count = 0;
- list<string> downlist;
-
- for ( list<string>::const_iterator it = retlist.begin(); it != retlist.end(); ++it ) {
- PathInfo cpath( cpath_r.path() + *it, PathInfo::LSTAT );
- if ( cpath.isFile() ) {
- count += phcAddFile( fd, cpath, prfx_r + *it );
- } else if ( options_r.recurse && cpath.isDir() ) {
- downlist.push_back( *it );
- }
- }
- retlist.clear();
-
- for ( list<string>::const_iterator it = downlist.begin(); it != downlist.end(); ++it ) {
- count += phcScanDir( fd, PathInfo(cpath_r.path() + *it), prfx_r + *it, options_r );
- }
-
- return count;
-}
-
-///////////////////////////////////////////////////////////////////
-//
-//
-// METHOD NAME : RpmHeaderCache::buildHeaderCache
-// METHOD TYPE : int
-//
-int RpmHeaderCache::buildHeaderCache( const Pathname & cache_r,
- const Pathname & pkgroot_r,
- const buildOpts & options_r )
-{
- ///////////////////////////////////////////////////////////////////
- // Check pkgroot
- ///////////////////////////////////////////////////////////////////
-
- PathInfo pkgroot( pkgroot_r );
- if ( !pkgroot.isDir() ) {
- ERR << "Not a directory: Pkgroot " << pkgroot << endl;
- return -1;
- }
-
- ///////////////////////////////////////////////////////////////////
- // Prepare cache file
- ///////////////////////////////////////////////////////////////////
- FD_t fd = ::Fopen( cache_r.asString().c_str(), "w" );
- if ( fd == 0 || ::Ferror(fd) ) {
- ERR << "Can't open cache for writing: " << cache_r << " (" << ::Fstrerror(fd) << ")" << endl;
- if ( fd )
- ::Fclose( fd );
- return -2;
- }
-
- phcAddMagic( fd );
-
- ///////////////////////////////////////////////////////////////////
- // Scan pkgroot_r
- ///////////////////////////////////////////////////////////////////
- MIL << "Start scan below " << pkgroot_r
- << " (recurse=" << (options_r.recurse?"yes":"no")
- << ")" << endl;
- unsigned count = phcScanDir( fd, pkgroot, "/", options_r );
-
- if ( ::Ferror(fd) ) {
- ERR << "Error writing cache: " << cache_r << " (" << ::Fstrerror(fd) << ")" << endl;
- ::Fclose( fd );
- return -3;
- }
-
- MIL << "Found " << count << " package(s) below " << pkgroot_r << endl;
- ::Fclose( fd );
- return count;
-}
-
- } // namespace rpm
- } // namespace target
-} // namespace zypp
+++ /dev/null
-/*---------------------------------------------------------------------\
-| ____ _ __ __ ___ |
-| |__ / \ / / . \ . \ |
-| / / \ V /| _/ _/ |
-| / /__ | | | | | | |
-| /_____||_| |_| |_| |
-| |
-\---------------------------------------------------------------------*/
-/** \file zypp/target/rpm/RpmHeaderCache.h
- *
-*/
-#ifndef ZYPP_TARGET_RPM_RPMHEADERCACHE_H
-#define ZYPP_TARGET_RPM_RPMHEADERCACHE_H
-
-#include <iosfwd>
-
-#include "zypp/Pathname.h"
-#include "zypp/target/rpm/BinHeaderCache.h"
-#include "zypp/target/rpm/RpmHeader.h"
-
-namespace zypp {
- namespace target {
- namespace rpm {
-
- ///////////////////////////////////////////////////////////////////
- //
- // CLASS NAME : RpmHeaderCache
- /**
- *
- **/
- class RpmHeaderCache : public BinHeaderCache {
-
- friend std::ostream & operator<<( std::ostream & str, const RpmHeaderCache & obj );
-
- RpmHeaderCache & operator=( const RpmHeaderCache & );
- RpmHeaderCache ( const RpmHeaderCache & );
-
- private:
-#warning Add this function if it is needed
-#if 0
- static const PkgNameEd & def_magic();
-
- protected:
-
- virtual bool magicOk();
-#endif
-
- public:
-
- RpmHeaderCache( const Pathname & cache_r );
- virtual ~RpmHeaderCache();
-
- RpmHeader::constPtr getFirst( Pathname & citem_r, int & isSource_r, pos & at_r );
- RpmHeader::constPtr getNext( Pathname & citem_r, int & isSource_r, pos & at_r );
-
- RpmHeader::constPtr getAt( pos at_r );
-
- public:
-
- struct buildOpts {
- bool recurse;
- buildOpts()
- : recurse( false )
- {}
- };
-
- static int buildHeaderCache( const Pathname & cache_r, const Pathname & pkgroot_r,
- const buildOpts & options_r = buildOpts() );
- };
-
- ///////////////////////////////////////////////////////////////////
-
- } // namespace rpm
- } // namespace target
-} // namespace zypp
-
-#endif // ZYPP_TARGET_RPM_RPMHEADERCACHE_H
+++ /dev/null
-/*---------------------------------------------------------------------\
-| |
-| __ __ ____ _____ ____ |
-| \ \ / /_ _/ ___|_ _|___ \ |
-| \ V / _` \___ \ | | __) | |
-| | | (_| |___) || | / __/ |
-| |_|\__,_|____/ |_| |_____| |
-| |
-| core system |
-| (C) SuSE Linux Products GmbH |
-\----------------------------------------------------------------------/
-
- File: TmpPath.cc
-
- Author: Michael Andres <ma@suse.de>
- Maintainer: Michael Andres <ma@suse.de>
-
- Purpose: Provide temporary files/directories, automaticaly
- deleted when no longer needed.
-
-/-*/
-
-#include <cstdlib>
-#include <cstring>
-#include <cerrno>
-
-#include <iostream>
-
-#include <y2util/Y2SLog.h>
-#include <y2util/PathInfo.h>
-#include <y2util/TmpPath.h>
-
-using namespace std;
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : TmpPath::Impl
-/**
- * Clean or delete a directory on destruction.
- **/
-class TmpPath::Impl :public Rep
-{
- public:
-
- enum Flags
- {
- NoOp = 0,
- Autodelete = 1L << 0,
- KeepTopdir = 1L << 1,
- //
- CtorDefault = Autodelete
- };
-
- public:
-
- Impl( const Pathname & path_r, Flags flags_r = CtorDefault )
- : _path( path_r ), _flags( flags_r )
- {}
-
- ~Impl()
- {
- if ( ! (_flags & Autodelete) || _path.empty() )
- return;
-
- PathInfo p( _path, PathInfo::LSTAT );
- if ( ! p.isExist() )
- return;
-
- int res = 0;
- if ( p.isDir() )
- {
- if ( _flags & KeepTopdir )
- res = PathInfo::clean_dir( _path );
- else
- res = PathInfo::recursive_rmdir( _path );
- }
- else
- res = PathInfo::unlink( _path );
-
- if ( res )
- INT << "TmpPath cleanup error (" << res << ") " << p << endl;
- else
- DBG << "TmpPath cleaned up " << p << endl;
- }
-
- const Pathname &
- path() const
- { return _path; }
-
- private:
- Pathname _path;
- Flags _flags;
-};
-///////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : TmpPath
-//
-///////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : TmpPath::TmpPath
-// METHOD TYPE : Constructor
-//
-TmpPath::TmpPath()
-:_impl( 0 ) // empty Pathname
-{
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : TmpPath::TmpPath
-// METHOD TYPE : Constructor
-//
-TmpPath::TmpPath( const Pathname & tmpPath_r )
-:_impl( tmpPath_r.empty() ? 0 : new Impl( tmpPath_r ) )
-{
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : TmpPath::~TmpPath
-// METHOD TYPE : Destructor
-//
-TmpPath::~TmpPath()
-{
- // virtual not inlined dtor.
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : TmpPath::operator const void *const
-// METHOD TYPE :
-//
-TmpPath::operator const void *const() const
-{
- return _impl;
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : TmpPath::path
-// METHOD TYPE : Pathname
-//
-Pathname
-TmpPath::path() const
-{
- return _impl ? _impl->path() : Pathname();
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : TmpPath::defaultLocation
-// METHOD TYPE : const Pathname &
-//
-const Pathname &
-TmpPath::defaultLocation()
-{
- static Pathname p( "/var/tmp" );
- return p;
-}
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : TmpFile
-//
-///////////////////////////////////////////////////////////////////
-
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : TmpFile::TmpFile
-// METHOD TYPE : Constructor
-//
-TmpFile::TmpFile( const Pathname & inParentDir_r,
- const std::string & prefix_r )
-{
- // parent dir must exist
- PathInfo p( inParentDir_r );
- if ( ! p.isDir() )
- {
- ERR << "Parent directory does not exist: " << p << endl;
- return;
- }
-
- // create the temp file
- Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
- char * buf = ::strdup( tmpPath.asString().c_str() );
- if ( ! buf )
- {
- ERR << "Out of memory" << endl;
- return;
- }
-
- int tmpFd = ::mkstemp( buf );
- if ( tmpFd != -1 )
- {
- // success; create _impl
- ::close( tmpFd );
- _impl = makeVarPtr( new Impl( buf ) );
- }
- else
- ERR << "Cant create '" << buf << "' " << ::strerror( errno ) << endl;
-
- ::free( buf );
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : TmpFile::defaultPrefix
-// METHOD TYPE : const std::string &
-//
-const std::string &
-TmpFile::defaultPrefix()
-{
- static string p( "TmpFile." );
- return p;
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : TmpDir
-//
-///////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : TmpDir::TmpDir
-// METHOD TYPE : Constructor
-//
-TmpDir::TmpDir( const Pathname & inParentDir_r,
- const std::string & prefix_r )
-{
- // parent dir must exist
- PathInfo p( inParentDir_r );
- if ( ! p.isDir() )
- {
- ERR << "Parent directory does not exist: " << p << endl;
- return;
- }
-
- // create the temp dir
- Pathname tmpPath = (inParentDir_r + prefix_r).extend( "XXXXXX");
- char * buf = ::strdup( tmpPath.asString().c_str() );
- if ( ! buf )
- {
- ERR << "Out of memory" << endl;
- return;
- }
-
- char * tmp = ::mkdtemp( buf );
- if ( tmp )
- // success; create _impl
- _impl = makeVarPtr( new Impl( tmp ) );
- else
- ERR << "Cant create '" << tmpPath << "' " << ::strerror( errno ) << endl;
-
- ::free( buf );
-}
-
-///////////////////////////////////////////////////////////////////
-//
-// METHOD NAME : TmpDir::defaultPrefix
-// METHOD TYPE : const std::string &
-//
-const std::string &
-TmpDir::defaultPrefix()
-{
- static string p( "TmpDir." );
- return p;
-}
+++ /dev/null
-/*---------------------------------------------------------------------\
-| |
-| __ __ ____ _____ ____ |
-| \ \ / /_ _/ ___|_ _|___ \ |
-| \ V / _` \___ \ | | __) | |
-| | | (_| |___) || | / __/ |
-| |_|\__,_|____/ |_| |_____| |
-| |
-| core system |
-| (C) SuSE Linux Products GmbH |
-\----------------------------------------------------------------------/
-
- File: TmpPath.h
-
- Author: Michael Andres <ma@suse.de>
- Maintainer: Michael Andres <ma@suse.de>
-
- Purpose: Provide temporary files/directories, automaticaly
- deleted when no longer needed.
-
-/-*/
-#ifndef TmpPath_h
-#define TmpPath_h
-
-#include <iosfwd>
-
-#include <y2util/Rep.h>
-#include <y2util/Pathname.h>
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : TmpPath
-/**
- * @short Automaticaly deletes files or directories when no longer needed.
- *
- * TmpPath is constructed from a Pathname. Multiple TmpPath instances created
- * by copy and assign, share the same reference counted internal repesentation.
-
- * When the last reference drops any file or directory located at the path
- * passed to the ctor is deleted (recursivly in case of directories).
- *
- * Principally serves as base class, but standalone usable.
- **/
-class TmpPath
-{
- public:
- /**
- * Default Ctor. An empty Pathname.
- **/
- TmpPath();
-
- /**
- * Ctor. Takes a Pathname.
- **/
- explicit
- TmpPath( const Pathname & tmpPath_r );
-
- /**
- * Dtor.
- **/
- virtual
- ~TmpPath();
-
- /**
- * Test whether the Pathname is valid (i.e. not empty. NOT whether
- * it realy denotes an existing file or directory).
- **/
- operator const void *const() const;
-
- /**
- * @return The Pathname.
- **/
- Pathname
- path() const;
-
- /**
- * Type conversion to Pathname.
- **/
- operator Pathname() const
- { return path(); }
-
- public:
- /**
- * @return The default directory where temporary
- * files should be are created (/var/tmp).
- **/
- static const Pathname &
- defaultLocation();
-
- protected:
- class Impl;
- VarPtr<Impl> _impl;
-};
-///////////////////////////////////////////////////////////////////
-
-/**
- * Stream output as pathname.
- **/
-inline std::ostream &
-operator<<( std::ostream & str, const TmpPath & obj )
-{ return str << static_cast<Pathname>(obj); }
-
-///////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : TmpFile
-/**
- * @short Provide a new empty temporary file and delete it when no
- * longer needed.
- *
- * The temporary file is per default created in '/var/tmp' and named
- ' TmpFile.XXXXXX', with XXXXXX replaced by a string which makes the
- * name unique. Different location and file prefix may be passed to
- * the ctor. TmpFile is created with mode 0600.
- *
- * The directory where the temporary file is to be created must exist.
- * TmpFile provides the Pathname of the temporary file, or an empty
- * path in case of any error.
- **/
-class TmpFile : public TmpPath
-{
- public:
- /**
- * Ctor. Takes a Pathname.
- **/
- explicit
- TmpFile( const Pathname & inParentDir_r = defaultLocation(),
- const std::string & prefix_r = defaultPrefix() );
-
- public:
- /**
- * @return The default prefix for temporary files (TmpFile.)
- **/
- static const std::string &
- defaultPrefix();
-
-};
-///////////////////////////////////////////////////////////////////
-
-///////////////////////////////////////////////////////////////////
-//
-// CLASS NAME : TmpDir
-/**
- * @short Provide a new empty temporary directory and recursively
- * delete it when no longer needed.
- *
- * The temporary directory is per default created in '/var/tmp' and
- ' named TmpDir.XXXXXX', with XXXXXX replaced by a string which makes
- * the name unique. Different location and file prefix may be passed
- * to the ctor. TmpDir is created with mode 0700.
- *
- * The directory where the temporary directory is to be created must exist.
- * TmpDir provides the Pathname of the temporary directory , or an empty
- * path in case of any error.
- **/
-class TmpDir : public TmpPath
-{
- public:
- /**
- * Ctor. Takes a Pathname.
- **/
- explicit
- TmpDir( const Pathname & inParentDir_r = defaultLocation(),
- const std::string & prefix_r = defaultPrefix() );
-
- public:
- /**
- * @return The default prefix for temporary directories (TmpDir.)
- **/
- static const std::string &
- defaultPrefix();
-};
-///////////////////////////////////////////////////////////////////
-
-#endif // TmpPath_h
+++ /dev/null
-/*---------------------------------------------------------------------\
-| |
-| __ __ ____ _____ ____ |
-| \ \ / /_ _/ ___|_ _|___ \ |
-| \ V / _` \___ \ | | __) | |
-| | | (_| |___) || | / __/ |
-| |_|\__,_|____/ |_| |_____| |
-| |
-| core system |
-| (C) SuSE GmbH |
-\----------------------------------------------------------------------/
-
- File: stringutil.cc
-
- Author: Michael Andres <ma@suse.de>
- Maintainer: Michael Andres <ma@suse.de>
-
- Purpose:
-
-/-*/
-
-#include <iostream>
-#include <fstream>
-
-#include <y2util/stringutil.h>
-
-using namespace std;
-///////////////////////////////////////////////////////////////////
-namespace stringutil {
-///////////////////////////////////////////////////////////////////
-
-const unsigned tmpBuffLen = 1024;
-char tmpBuff[tmpBuffLen];
-
-/******************************************************************
-**
-**
-** FUNCTION NAME : getline
-** FUNCTION TYPE : std::string
-**
-** DESCRIPTION :
-*/
-static inline std::string _getline( std::istream & str, const Trim trim_r )
-{
- string ret;
- do {
- str.clear();
- str.getline( tmpBuff, tmpBuffLen ); // always writes '\0' terminated
- ret += tmpBuff;
- } while( str.rdstate() == ios::failbit );
-
- return trim( ret, trim_r );
-}
-
-std::string getline( std::istream & str, const Trim trim_r )
-{
- return _getline(str, trim_r);
-}
-
-std::string getline( std::istream & str, bool trim )
-{
- return _getline(str, trim?TRIM:NO_TRIM);
-}
-
-/******************************************************************
-**
-**
-** FUNCTION NAME : split
-** FUNCTION TYPE : unsigned
-**
-** DESCRIPTION :
-*/
-unsigned split( const std::string line_tv,
- std::vector<std::string> & words_Vtr,
- const std::string & sep_tv,
- const bool singlesep_bv )
-{
- words_Vtr.clear();
- if ( line_tv.empty() )
- return words_Vtr.size();
-
- struct sepctrl {
- const string & sep_t;
- sepctrl( const string & sep_tv ) : sep_t( sep_tv ) {}
- // Note that '\0' ist neither Sep nor NonSep
- inline bool isSep ( const char c ) const { return( sep_t.find( c ) != string::npos ); }
- inline bool isNonSep ( const char c ) const { return( c && !isSep(c) ); }
- inline void skipSep ( const char *& p ) const { while ( isSep( *p ) ) ++p; }
- inline void skipNonSep( const char *& p ) const { while ( isNonSep( *p ) ) ++p; }
- };
-
- sepctrl sep_Ci( sep_tv );
- const char * s_pci = line_tv.c_str();
- const char * c_pci = s_pci;
-
- // Start with c_pci at the beginning of the 1st field to add.
- // In singlesep the beginning might be equal to the next sep,
- // which makes an empty field before the sep.
- if ( !singlesep_bv && sep_Ci.isSep( *c_pci ) ) {
- sep_Ci.skipSep( c_pci );
- }
-
- for ( s_pci = c_pci; *s_pci; s_pci = c_pci ) {
- sep_Ci.skipNonSep( c_pci );
- words_Vtr.push_back( string( s_pci, c_pci - s_pci ) );
- if ( *c_pci ) {
- if ( singlesep_bv ) {
- if ( !*(++c_pci) ) {
- // line ends with a sep -> add the empty field behind
- words_Vtr.push_back( "" );
- }
- } else
- sep_Ci.skipSep( c_pci );
- }
- }
-
- return words_Vtr.size();
-}
-
-/******************************************************************
-**
-**
-** FUNCTION NAME : join
-** FUNCTION TYPE : std::string
-**
-** DESCRIPTION :
-*/
-std::string join( const std::vector<std::string> & words_r,
- const std::string & sep_r )
-{
- if ( words_r.empty() )
- return "";
-
- string ret( words_r[0] );
-
- for ( unsigned i = 1; i < words_r.size(); ++i ) {
- ret += sep_r + words_r[i];
- }
-
- return ret;
-}
-
-/******************************************************************
-**
-**
-** FUNCTION NAME : stripFirstWord
-** FUNCTION TYPE : std::string
-**
-** DESCRIPTION :
-*/
-string stripFirstWord( string & line, const bool ltrim_first )
-{
- if ( ltrim_first )
- line = ltrim( line );
-
- if ( line.empty() )
- return line;
-
- string ret;
- string::size_type p = line.find_first_of( " \t" );
-
- if ( p == string::npos ) {
- // no ws on line
- ret = line;
- line.erase();
- } else if ( p == 0 ) {
- // starts with ws
- // ret remains empty
- line = ltrim( line );
- }
- else {
- // strip word and ltim line
- ret = line.substr( 0, p );
- line = ltrim( line.erase( 0, p ) );
- }
- return ret;
-}
-
-///////////////////////////////////////////////////////////////////
-} // namespace stringutil
-///////////////////////////////////////////////////////////////////
-
+++ /dev/null
-/*---------------------------------------------------------------------\
-| |
-| __ __ ____ _____ ____ |
-| \ \ / /_ _/ ___|_ _|___ \ |
-| \ V / _` \___ \ | | __) | |
-| | | (_| |___) || | / __/ |
-| |_|\__,_|____/ |_| |_____| |
-| |
-| core system |
-| (C) SuSE GmbH |
-\----------------------------------------------------------------------/
-
- File: stringutil.h
-
- Author: Michael Andres <ma@suse.de>
- Maintainer: Michael Andres <ma@suse.de>
-
- Purpose: Contains 'std::string form(const char * format, ...)' for
- printf style creation of strings and some more string utility
- functions.
-
-/-*/
-
-#ifndef stringutil_h
-#define stringutil_h
-
-#include <cstdio>
-#include <cstdarg>
-
-#include <iosfwd>
-#include <vector>
-#include <string>
-#include <list>
-
-/**
- * Utility functions for std::strings. Most of them based on stringutil::form.
- **/
-///////////////////////////////////////////////////////////////////
-namespace stringutil {
-;//////////////////////////////////////////////////////////////////
-
-/** \brief read one line from a stream
- *
- * like above but with allows to specify trimming direction
- * */
-extern std::string getline( std::istream & str, const Trim trim_r );
-
-/**
- * Split line into words
- *
- * <b>singlesep_r = false</b>: Separator is any nonenmpty sequence of characters listed in sep_t.
- * Leading trailing separators are ignored.
- *
- * <b>Example:</b> singlesep_r = false, sep_t = ":"
- * <PRE>
- * "" -> words 0
- * ":" -> words 0
- * "a" -> words 1 |a|
- * "::a" -> words 1 |a|
- * "::a::" -> words 1 |a|
- * ":a::b:c:"-> words 3 |a|b|c|
- * </PRE>
- *
- * <b>singlesep_r = true</b>: Separator is any single character occuring in sep_t.
- * Leading trailing separators are not ignored (i.e will cause an empty word).
- *
- * <b>Example:</b> singlesep_r = true, sep_t = ":"
- * <PRE>
- * "" -> words 0
- * ":" -> words 2 |||
- * "a" -> words 1 |a|
- * ":a" -> words 2 ||a|
- * "a:" -> words 2 |a||
- * ":a:" -> words 3 ||a||
- * </PRE>
- *
- **/
-extern unsigned split( const std::string line_r,
- std::vector<std::string> & words_r,
- const std::string & sep_t = " \t",
- const bool singlesep_r = false );
-
-/**
- * Join strinngs in words_r using separator sep_r
- **/
-extern std::string join( const std::vector<std::string> & words_r,
- const std::string & sep_r = " " );
-
-
-/**
- * Split string into a list of lines using <b>any<\b> char in sep_r as line
- * delimiter. The delimiter is stripped from the line.
- *
- * <PRE>
- * splitToLines( "start\n\nend" ) -> { "start", "", "end" }
- * </PRE>
- **/
-inline std::list<std::string> splitToLines( const std::string text_r, const std::string & sep_r = "\n" )
-{
- std::vector<std::string> lines;
- stringutil::split( text_r, lines, "\n", true );
- std::list<std::string> ret;
- for ( unsigned i = 0; i < lines.size(); ++i ) {
- ret.push_back( lines[i] );
- }
- return ret;
-}
-
-/**
- * Strip the first word (delimited by blank or tab) from value, and return it.
- * Adjust value to start with the second word afterwards.
- *
- * If value starts with blank or tab, the <b>first word is empty</b> and value will be
- * ltrimmed afterwards.
- *
- * If ltrim_first is true, value will be ltrimmed before stripping the first word. Thus
- * first word is empty, iff value is empty or contains whitespace only.
- *
- * <PRE>
- * stripFirstWord( "1st" ) == "1st" and value truncated to ""
- * stripFirstWord( "1st word" ) == "1st" and value truncated to "word"
- * stripFirstWord( " 1st word" ) == "" and value truncated to "1st word"
- * stripFirstWord( " 1st word", true ) == "1st" and value truncated to "word"
- * </PRE>
- **/
-extern std::string stripFirstWord( std::string & value, const bool ltrim_first = false );
-
-/**
- * Return string with leading/trailing/surrounding whitespace removed
- **/
-extern std::string ltrim( const std::string & s );
-extern std::string rtrim( const std::string & s );
-inline std::string trim( const std::string & s, const Trim trim_r = TRIM ) {
- switch ( trim_r ) {
- case L_TRIM:
- return ltrim( s );
- case R_TRIM:
- return rtrim( s );
- case TRIM:
- return ltrim( rtrim( s ) );
- case NO_TRIM:
- break;
- }
- return s;
-}
-
-///////////////////////////////////////////////////////////////////
-} // namespace stringutil
-///////////////////////////////////////////////////////////////////
-
-#endif // stringutil_h