From 199115866064770acacc7d42bb1a89a57818276d Mon Sep 17 00:00:00 2001 From: Robert Collins Date: Sun, 5 May 2002 04:02:01 +0000 Subject: [PATCH] 2002-05-05 Robert Collins * Makefile.am (noinst_PROGRAMS): Make inilint configurable. * configure.in: Ditto. Fix incorrect header checking syntax. * aclocal.m4: Regenerate. * configure: Regenerate. * Makefile.in: Regenerate. * io_stream.cc: Remove platform specific and provider specific code. (io_stream::registerProvider): New method, registers a Url provider with the io_stream code. Make all methods consistently throw invalid_argument exceptions when a provider that is requested is not present. (findProvider): New private function, finds a provider. * io_stream.h: Declare io_stream::registerProvider. * io_stream_cygfile.cc: Create a Provider class to register with io_stream.cc. * io_stream_file.cc: Ditto. * archive.cc: Remove unneeded includes. * archive_tar.cc: Remove unneeded includes. * archive_tar.h: Add required include. * archive_tar_file.cc: Remove unneded includes. * choose.cc: Remove unneeded includes: --- ChangeLog | 24 ++++++ IOStreamProvider.h | 43 ++++++++++ Makefile.am | 7 +- Makefile.in | 8 +- archive.cc | 8 +- archive_tar.cc | 1 - archive_tar.h | 1 + archive_tar_file.cc | 5 -- choose.cc | 1 - configure | 129 ++++++++++++++++++++++++----- configure.ac | 21 ++++- configure.in | 21 ++++- io_stream.cc | 192 +++++++++++++++++-------------------------- io_stream.h | 3 + io_stream_cygfile.cc | 31 +++++++ io_stream_file.cc | 32 ++++++++ 16 files changed, 367 insertions(+), 160 deletions(-) create mode 100644 IOStreamProvider.h diff --git a/ChangeLog b/ChangeLog index 821151b1..49b26d7b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2002-05-05 Robert Collins + + * Makefile.am (noinst_PROGRAMS): Make inilint configurable. + * configure.in: Ditto. + Fix incorrect header checking syntax. + * aclocal.m4: Regenerate. + * configure: Regenerate. + * Makefile.in: Regenerate. + * io_stream.cc: Remove platform specific and provider specific code. + (io_stream::registerProvider): New method, registers a Url provider with + the io_stream code. + Make all methods consistently throw invalid_argument exceptions when + a provider that is requested is not present. + (findProvider): New private function, finds a provider. + * io_stream.h: Declare io_stream::registerProvider. + * io_stream_cygfile.cc: Create a Provider class to register with + io_stream.cc. + * io_stream_file.cc: Ditto. + * archive.cc: Remove unneeded includes. + * archive_tar.cc: Remove unneeded includes. + * archive_tar.h: Add required include. + * archive_tar_file.cc: Remove unneded includes. + * choose.cc: Remove unneeded includes: + 2002-05-04 Robert Collins * io_stream.cc: Use the new log interface thruout. diff --git a/IOStreamProvider.h b/IOStreamProvider.h new file mode 100644 index 00000000..d18b9e70 --- /dev/null +++ b/IOStreamProvider.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2002, Robert Collins. + * + * 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. + * + * A copy of the GNU General Public License can be found at + * http://www.gnu.org/ + * + * Written by Robert Collins + * + */ + +#ifndef _IOSTREAMPROVIDER_H_ +#define _IOSTREAMPROVIDER_H_ + +#include "io_stream.h" +#include "String++.h" + +/* An IOStreamProvider provides the interface for io_stream::open and + * related calls to operate. + */ + +class IOStreamProvider +{ +public: + virtual int exists (String const &) const = 0; + virtual int remove (String const &) const = 0; + virtual int mklink (String const &, String const &, io_stream_link_t) const = 0; + virtual io_stream *open (String const &,String const &) const = 0; + virtual ~IOStreamProvider (){} + virtual int move (String const &,String const &) const = 0; + virtual int mkdir_p (enum path_type_t isadir, String const &path) const = 0; + String key; // Do not set - managed automatically. +protected: + IOStreamProvider(){} // no base instances + IOStreamProvider(IOStreamProvider const &); // no copy cons + IOStreamProvider &operator=(IOStreamProvider const &); // no assignment +}; + +#endif /* _IOSTREAMPROVIDER_H_ */ diff --git a/Makefile.am b/Makefile.am index 2ddb8714..703efb45 100644 --- a/Makefile.am +++ b/Makefile.am @@ -33,10 +33,11 @@ WINDRES := @WINDRES@ INCLUDES = -I$(srcdir)/bz2lib -I$(srcdir)/libgetopt++/include noinst_PROGRAMS = \ - setup + setup \ + @INILINT@ EXTRA_PROGRAMS = inilint -##noinst_PROGRAMS +=inilint +## noinst_PROGRAMS +=inilint # to avoid false errors that assembly generates WARNONLY_CFLAGS = -Winline -Wall -Wpointer-arith -Wcast-align \ @@ -71,6 +72,7 @@ inilint_SOURCES = \ iniparse.h \ io_stream.h \ io_stream.cc \ + IOStreamProvider.h \ PackageTrust.h \ rfc1738.cc \ rfc1738.h \ @@ -141,6 +143,7 @@ setup_SOURCES = \ io_stream_file.h \ io_stream_memory.cc \ io_stream_memory.h \ + IOStreamProvider.h \ list.h \ localdir.cc \ localdir.h \ diff --git a/Makefile.in b/Makefile.in index 326716ad..20b93e0b 100644 --- a/Makefile.in +++ b/Makefile.in @@ -94,6 +94,7 @@ DLLTOOL = @DLLTOOL@ ECHO = @ECHO@ GCJ = @GCJ@ GCJFLAGS = @GCJFLAGS@ +INILINT = @INILINT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ LEX = @LEX@ LEXLIB = @LEXLIB@ @@ -126,7 +127,8 @@ AM_CXXFLAGS = $(AM_CFLAGS) INCLUDES = -I$(srcdir)/bz2lib -I$(srcdir)/libgetopt++/include noinst_PROGRAMS = \ - setup + setup \ + @INILINT@ EXTRA_PROGRAMS = inilint @@ -167,6 +169,7 @@ inilint_SOURCES = \ iniparse.h \ io_stream.h \ io_stream.cc \ + IOStreamProvider.h \ PackageTrust.h \ rfc1738.cc \ rfc1738.h \ @@ -239,6 +242,7 @@ setup_SOURCES = \ io_stream_file.h \ io_stream_memory.cc \ io_stream_memory.h \ + IOStreamProvider.h \ list.h \ localdir.cc \ localdir.h \ @@ -331,7 +335,7 @@ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 mkinstalldirs = $(SHELL) $(top_srcdir)/cfgaux/mkinstalldirs CONFIG_CLEAN_FILES = EXTRA_PROGRAMS = inilint$(EXEEXT) -noinst_PROGRAMS = setup$(EXEEXT) +noinst_PROGRAMS = setup$(EXEEXT) @INILINT@ PROGRAMS = $(noinst_PROGRAMS) am_inilint_OBJECTS = filemanip.$(OBJEXT) LogSingleton.$(OBJEXT) \ diff --git a/archive.cc b/archive.cc index b63276c4..682c1b2f 100644 --- a/archive.cc +++ b/archive.cc @@ -21,11 +21,11 @@ static const char *cvsid = "\n%%% $Id$\n"; #endif -#include "win32.h" -#include -#include +//#include "win32.h" +//#include +//#include #include "LogSingleton.h" -#include "port.h" +//#include "port.h" #include "String++.h" #include "io_stream.h" diff --git a/archive_tar.cc b/archive_tar.cc index ad7c1f6e..66ea3859 100644 --- a/archive_tar.cc +++ b/archive_tar.cc @@ -20,7 +20,6 @@ static const char *cvsid = "\n%%% $Id$\n"; #endif -#include "win32.h" #include #include #include diff --git a/archive_tar.h b/archive_tar.h index bf03ae1e..2b342161 100644 --- a/archive_tar.h +++ b/archive_tar.h @@ -21,6 +21,7 @@ #include "io_stream.h" #include "archive.h" #include "String++.h" +#include "win32.h" typedef struct { diff --git a/archive_tar_file.cc b/archive_tar_file.cc index 2deaf9d4..4385c2a6 100644 --- a/archive_tar_file.cc +++ b/archive_tar_file.cc @@ -19,11 +19,6 @@ static const char *cvsid = "\n%%% $Id$\n"; #endif -#include "win32.h" -#include -#include -#include -#include #include #include "zlib/zlib.h" diff --git a/choose.cc b/choose.cc index c428b202..7fc8ed60 100644 --- a/choose.cc +++ b/choose.cc @@ -33,7 +33,6 @@ static const char *cvsid = #include "win32.h" #include #include -#include #include #include #include diff --git a/configure b/configure index 2c20c08b..3cd84b78 100755 --- a/configure +++ b/configure @@ -998,6 +998,7 @@ Optional Features: --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer + --enable-inilint Build the inilint tool --disable-dependency-tracking Speeds up one-time builds --enable-dependency-tracking Do not reject slow dependency extractors --enable-shared[=PKGS] @@ -1783,6 +1784,24 @@ fi +echo "$as_me:$LINENO: checking Whether to build inilint" >&5 +echo $ECHO_N "checking Whether to build inilint... $ECHO_C" >&6 +# Check whether --enable-inilint or --disable-inilint was given. +if test "${enable_inilint+set}" = set; then + enableval="$enable_inilint" + ac_cv_enable_inilint=$enableval +else + ac_cv_enable_inilint=no +fi; +echo "$as_me:$LINENO: result: $ac_cv_enable_inilint" >&5 +echo "${ECHO_T}$ac_cv_enable_inilint" >&6 +if test $ac_cv_enable_inilint = yes; then + INILINT="inilint" +else + INILINT= +fi + + ac_ext=cc ac_cpp='$CXXCPP $CPPFLAGS' ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -4084,7 +4103,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 4087 "configure"' > conftest.$ac_ext + echo '#line 4106 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -7783,7 +7802,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext < conftest.$ac_ext <&5 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 if eval "test \"\${$as_ac_Header+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 +echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 else - cat >conftest.$ac_ext <<_ACEOF + # Is the header compilable? +echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" #include "confdefs.h" -\ - string.h - +$ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext @@ -14975,25 +15006,82 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then - eval "$as_ac_Header=yes" + ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 cat conftest.$ac_ext >&5 -eval "$as_ac_Header=no" +ac_header_compiler=no fi rm -f conftest.$ac_objext conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6 + +# Is the header present? +echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6 +cat >conftest.$ac_ext <<_ACEOF +#line $LINENO "configure" +#include "confdefs.h" +#include <$ac_header> +_ACEOF +if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 + (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 + ac_status=$? + egrep -v '^ *\+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_header_preproc=no +fi +rm -f conftest.err conftest.$ac_ext +echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6 + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc in + yes:no ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; + no:yes ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;};; +esac +echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6 +if eval "test \"\${$as_ac_Header+set}\" = set"; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=$ac_header_preproc" fi echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5 echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6 + +fi if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF - \ - errno.h -else - \ - string + fi done @@ -15638,6 +15726,7 @@ s,@SET_MAKE@,$SET_MAKE,;t t s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t s,@MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t s,@MAINT@,$MAINT,;t t +s,@INILINT@,$INILINT,;t t s,@CXX@,$CXX,;t t s,@CXXFLAGS@,$CXXFLAGS,;t t s,@LDFLAGS@,$LDFLAGS,;t t diff --git a/configure.ac b/configure.ac index 468866eb..c937f1ab 100644 --- a/configure.ac +++ b/configure.ac @@ -26,6 +26,19 @@ AM_MAINTAINER_MODE AC_CONFIG_SRCDIR([Makefile.in]) AC_REVISION($Revision$)dnl +AC_MSG_CHECKING([Whether to build inilint]) +AC_ARG_ENABLE(inilint, + AC_HELP_STRING([--enable-inilint], + [Build the inilint tool]), + ac_cv_enable_inilint=$enableval, ac_cv_enable_inilint=no) +AC_MSG_RESULT([$ac_cv_enable_inilint]) +if test $ac_cv_enable_inilint = yes; then + INILINT="inilint" +else + INILINT= +fi +AC_SUBST(INILINT) + AC_LANG_CPLUSPLUS AC_PROG_CXX AM_PROG_CC_C_O @@ -52,10 +65,10 @@ dnl AC_SUBST(OBJCOPY) AC_CHECK_LIB(mingw32,main) -AC_CHECK_HEADERS(alloca.h, \ - errno.h, \ - string, \ - string.h) +AC_CHECK_HEADERS(alloca.h \ + errno.h \ + string \ + string.h ) AC_CONFIG_SUBDIRS(zlib) AC_CONFIG_SUBDIRS(bz2lib) diff --git a/configure.in b/configure.in index 468866eb..c937f1ab 100644 --- a/configure.in +++ b/configure.in @@ -26,6 +26,19 @@ AM_MAINTAINER_MODE AC_CONFIG_SRCDIR([Makefile.in]) AC_REVISION($Revision$)dnl +AC_MSG_CHECKING([Whether to build inilint]) +AC_ARG_ENABLE(inilint, + AC_HELP_STRING([--enable-inilint], + [Build the inilint tool]), + ac_cv_enable_inilint=$enableval, ac_cv_enable_inilint=no) +AC_MSG_RESULT([$ac_cv_enable_inilint]) +if test $ac_cv_enable_inilint = yes; then + INILINT="inilint" +else + INILINT= +fi +AC_SUBST(INILINT) + AC_LANG_CPLUSPLUS AC_PROG_CXX AM_PROG_CC_C_O @@ -52,10 +65,10 @@ dnl AC_SUBST(OBJCOPY) AC_CHECK_LIB(mingw32,main) -AC_CHECK_HEADERS(alloca.h, \ - errno.h, \ - string, \ - string.h) +AC_CHECK_HEADERS(alloca.h \ + errno.h \ + string \ + string.h ) AC_CONFIG_SUBDIRS(zlib) AC_CONFIG_SUBDIRS(bz2lib) diff --git a/io_stream.cc b/io_stream.cc index 22bb3728..1321a037 100644 --- a/io_stream.cc +++ b/io_stream.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, Robert Collins. + * Copyright (c) 2001, 2002, Robert Collins. * * 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 @@ -24,16 +24,49 @@ static const char *cvsid = "\n%%% $Id$\n"; #endif -#include "win32.h" -#include #include "LogSingleton.h" -#include "port.h" #include "io_stream.h" -#include "io_stream_file.h" -#include "io_stream_cygfile.h" -#include "mkdir.h" #include "String++.h" +#include "list.h" +#include +#include "IOStreamProvider.h" + +static list *providers; +static size_t longestPrefix = 0; +static int inited = 0; + +void +io_stream::registerProvider (IOStreamProvider &theProvider, + String const &urlPrefix) +{ + if (!inited) + { + providers = new list ; + inited = true; + } + theProvider.key = urlPrefix; + IOStreamProvider const &testProvider = providers->registerbyobject (theProvider); + if (&testProvider != &theProvider) + throw new invalid_argument ("urlPrefix already registered!"); + if (urlPrefix.size() > longestPrefix) + longestPrefix = urlPrefix.size(); +} + +static IOStreamProvider const * +findProvider (String const &path) +{ + if (path.size() < longestPrefix) + return NULL; + for (unsigned int i = 1; i <= providers->number(); ++i) + { + IOStreamProvider const *p = (*providers)[i]; + if (!path.casecompare (p->key, p->key.size())) + return p; + } + return NULL; +} /* Static members */ io_stream * @@ -54,58 +87,33 @@ io_stream::factory (io_stream * parent) io_stream * io_stream::open (String const &name, String const &mode) { - if (name.size() < 7 || - mode.size() == 0) - return NULL; - /* iterate through the known url prefix's */ - if (!name.casecompare ("file://", 7)) - { - io_stream_file *rv = new io_stream_file (&name.cstr_oneuse()[7], mode.cstr_oneuse()); - if (!rv->error ()) - return rv; - delete rv; - return NULL; - } - if (!name.casecompare ("cygfile://", 10)) - { - io_stream_cygfile *rv = new io_stream_cygfile (&name.cstr_oneuse()[10], mode.cstr_oneuse()); - if (!rv->error ()) - return rv; - delete rv; - return NULL; - } + IOStreamProvider const *p = findProvider (name); + if (!p) + throw new invalid_argument ("URL Scheme not registered!"); + io_stream *rv = p->open (&name.cstr_oneuse()[p->key.size()], mode); + if (!rv->error ()) + return rv; + delete rv; return NULL; } int io_stream::mkpath_p (path_type_t isadir, String const &name) { - if (name.size() < 7) - return 1; - /* iterate through the known url prefix's */ - if (!name.casecompare ("file://", 7)) - { - return mkdir_p (isadir == PATH_TO_DIR ? 1 : 0, &name.cstr_oneuse()[7]); - } - if (!name.casecompare ("cygfile://", 10)) - { - return cygmkdir_p (isadir, &name.cstr_oneuse()[10]); - } - return 1; + IOStreamProvider const *p = findProvider (name); + if (!p) + throw new invalid_argument ("URL Scheme not registered!"); + return p->mkdir_p (isadir, &name.cstr_oneuse()[p->key.size()]); } /* remove a file or directory. */ int io_stream::remove (String const &name) { - if (!name.size()) - return 1; - /* iterate through the known url prefix's */ - if (!name.casecompare ("file://", 7)) - return io_stream_file::remove (&name.cstr_oneuse()[7]); - if (!name.casecompare ("cygfile://", 10)) - return io_stream_cygfile::remove (&name.cstr_oneuse()[10]); - return 1; + IOStreamProvider const *p = findProvider (name); + if (!p) + throw new invalid_argument ("URL Scheme not registered!"); + return p->remove (&name.cstr_oneuse()[p->key.size()]); } int @@ -114,39 +122,14 @@ io_stream::mklink (String const &from, String const &to, { log (LOG_BABBLE) << "io_stream::mklink (" << from << "->" << to << ")" << endLog; - if (!from.size() || !to.size()) - { - log (LOG_TIMESTAMP) << "invalid string in from or to parameters to mklink" - << endLog; - return 1; - } - /* iterate through the known url prefixes */ - if (!from.casecompare ("file://", 7)) - { - /* file urls can symlink or hardlink to file url's. */ - /* TODO: allow linking to cygfile url's */ - if (!to.casecompare ("file://", 7)) - return io_stream_file::mklink (&from.cstr_oneuse()[7], &to.cstr_oneuse()[7], linktype); - log (LOG_TIMESTAMP) << "Attempt to link across url providers" << endLog; - return 1; - } - if (!from.casecompare ("cygfile://", 10)) - { - /* cygfile urls can symlink or hardlink to cygfile urls's. */ - /* TODO: allow -> file urls */ - if (!to.casecompare ("cygfile://", 10)) - return io_stream_cygfile::mklink (&from.cstr_oneuse()[10], &to.cstr_oneuse()[10], linktype); - log (LOG_TIMESTAMP) << "Attempt to link across url providers" << endLog; - return 1; - } -#if 0 - if (!strmcasecmp ("http://", from, 7)) - { - /* http urls can symlink to http or ftp url's */ - } -#endif - log (LOG_TIMESTAMP) << "Unsupported url providers for " << from << endLog; - return 1; + IOStreamProvider const *fromp = findProvider (from); + IOStreamProvider const *top = findProvider (to); + if (!fromp || !top) + throw new invalid_argument ("URL Scheme not registered!"); + if (fromp != top) + throw new invalid_argument ("Attempt to link across url providers."); + return fromp->mklink (&from.cstr_oneuse()[fromp->key.size()], + &to.cstr_oneuse()[top->key.size()], linktype); } int @@ -203,35 +186,14 @@ ssize_t io_stream::copy (io_stream * in, io_stream * out) int io_stream::move (String const &from, String const &to) { - if (!from.size() || !to.size()) - { - log (LOG_TIMESTAMP) << "invalid string in from or to parameters to move" - << endLog; - return 1; - } - /* iterate through the known url prefixes */ - if (!from.casecompare ("file://", 7)) - { - /* TODO: allow 'move' to cygfile url's */ - if (to.casecompare ("file://", 7)) - return io_stream::move_copy (from, to); - return io_stream_file::move (&from.cstr_oneuse()[7], &to.cstr_oneuse()[7]); - } - if (!from.casecompare ("cygfile://", 10)) - { - /* TODO: allow -> file urls */ - if (to.casecompare ("cygfile://", 10)) - return io_stream::move_copy (from, to); - return io_stream_cygfile::move (&from.cstr_oneuse()[10], &to.cstr_oneuse()[10]); - } -#if 0 - if (!strmcasecmp ("http://", from, 7)) - { - /* http urls can symlink to http or ftp url's */ - } -#endif - log (LOG_TIMESTAMP) << "Unsupported url providers for " << from << endLog; - return 1; + IOStreamProvider const *fromp = findProvider (from); + IOStreamProvider const *top = findProvider (to); + if (!fromp || !top) + throw new invalid_argument ("URL Scheme not registered!"); + if (fromp != top) + return io_stream::move_copy (from, to); + return fromp->move (&from.cstr_oneuse()[fromp->key.size()], + &to.cstr_oneuse()[top->key.size()]); } char * @@ -261,14 +223,10 @@ io_stream::gets (char *buffer, size_t length) int io_stream::exists (String const &name) { - if (!name.size()) - return 1; - /* iterate through the known url prefix's */ - if (!name.casecompare ("file://", 7)) - return io_stream_file::exists (&name.cstr_oneuse()[7]); - if (!name.casecompare ("cygfile://", 10)) - return io_stream_cygfile::exists (&name.cstr_oneuse()[10]); - return 1; + IOStreamProvider const *p = findProvider (name); + if (!p) + throw new invalid_argument ("URL Scheme not registered!"); + return p->exists (&name.cstr_oneuse()[p->key.size()]); } /* virtual members */ diff --git a/io_stream.h b/io_stream.h index c7d5da97..669ddd1d 100644 --- a/io_stream.h +++ b/io_stream.h @@ -24,6 +24,7 @@ #include #include "String++.h" +class IOStreamProvider; /* Some things don't fit cleanly just - TODO * make mkdir_p fit in the hierarchy @@ -72,6 +73,8 @@ io_stream_seek_t; class io_stream { public: + /* Register a new io_stream provider */ + static void registerProvider (IOStreamProvider &, String const &urlscheme); /* create a new stream from an existing one - used to get * decompressed data * or open archives. diff --git a/io_stream_cygfile.cc b/io_stream_cygfile.cc index 34a9d836..e1e07894 100644 --- a/io_stream_cygfile.cc +++ b/io_stream_cygfile.cc @@ -32,6 +32,37 @@ static const char *cvsid = #include "io_stream.h" #include "io_stream_cygfile.h" +#include "IOStreamProvider.h" + +/* completely private iostream registration class */ +class CygFileProvider : public IOStreamProvider +{ +public: + int exists (String const &path) const + {return io_stream_cygfile::exists(path);} + int remove (String const &path) const + {return io_stream_cygfile::remove(path);} + int mklink (String const &a , String const &b, io_stream_link_t c) const + {return io_stream_cygfile::mklink(a,b,c);} + io_stream *open (String const &a,String const &b) const + {return new io_stream_cygfile (a, b);} + ~CygFileProvider (){} + int move (String const &a,String const &b) const + {return io_stream_cygfile::move (a, b);} + int mkdir_p (enum path_type_t isadir, String const &path) const + {return cygmkdir_p (isadir, path);} +protected: + CygFileProvider() // no creating this + { + io_stream::registerProvider (theInstance, "cygfile://"); + } + CygFileProvider(CygFileProvider const &); // no copying + CygFileProvider &operator=(CygFileProvider const &); // no assignment +private: + static CygFileProvider theInstance; +}; +CygFileProvider CygFileProvider::theInstance = CygFileProvider(); + /* For set mtime */ #define FACTOR (0x19db1ded53ea710LL) diff --git a/io_stream_file.cc b/io_stream_file.cc index ef7db81b..f9018e38 100644 --- a/io_stream_file.cc +++ b/io_stream_file.cc @@ -24,10 +24,42 @@ static const char *cvsid = #include #include #include "port.h" +#include "mkdir.h" #include "mklink2.h" #include "io_stream.h" #include "io_stream_file.h" +#include "IOStreamProvider.h" + +/* completely private iostream registration class */ +class FileProvider : public IOStreamProvider +{ +public: + int exists (String const &path) const + {return io_stream_file::exists(path);} + int remove (String const &path) const + {return io_stream_file::remove(path);} + int mklink (String const &a , String const &b, io_stream_link_t c) const + {return io_stream_file::mklink(a,b,c);} + io_stream *open (String const &a,String const &b) const + {return new io_stream_file (a, b);} + ~FileProvider (){} + int move (String const &a,String const &b) const + {return io_stream_file::move (a, b);} + int mkdir_p (enum path_type_t isadir, String const &path) const + {return ::mkdir_p (isadir == PATH_TO_DIR ? 1 : 0, path.cstr_oneuse());} +protected: + FileProvider() // no creating this + { + io_stream::registerProvider (theInstance, "file://"); + } + FileProvider(FileProvider const &); // no copying + FileProvider &operator=(FileProvider const &); // no assignment +private: + static FileProvider theInstance; +}; +FileProvider FileProvider::theInstance = FileProvider(); + /* for set_mtime */ #define FACTOR (0x19db1ded53ea710LL) -- 2.43.5