mirror of
https://github.com/PDB-REDO/libcifpp.git
synced 2026-06-06 23:34:21 +08:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
791ab245ca | ||
|
|
43287736bb | ||
|
|
34ee3321d8 | ||
|
|
6e433ae784 | ||
|
|
cd370275da | ||
|
|
7ed0f4c8ae | ||
|
|
ea7d8ce766 | ||
|
|
f12e877251 | ||
|
|
57ce90ce7c | ||
|
|
b61321e360 | ||
|
|
6416056958 | ||
|
|
4fdfd03c04 | ||
|
|
a1d2438341 | ||
|
|
952aa15d6e | ||
|
|
b3e45eb0b6 | ||
|
|
a548b39677 | ||
|
|
d5d96c58e4 |
17
.travis.yml
17
.travis.yml
@@ -19,18 +19,15 @@ addons:
|
||||
- libboost-all-dev
|
||||
|
||||
before_install:
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew update ; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install make; fi
|
||||
|
||||
# - if [ "$TRAVIS_OS_NAME" = "osx" ]; then brew install boost make; fi
|
||||
|
||||
script:
|
||||
- ./configure
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then gmake NO_REVISION=1 ; else make NO_REVISION=1 ; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then gmake test NO_REVISION=1 ; else make test NO_REVISION=1 ; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then sudo gmake NO_REVISION=1 install; else sudo make install NO_REVISION=1; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then ./configure --disable-shared ; else ./configure ; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then gmake ; else make ; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then gmake test ; else make test ; fi
|
||||
- if [ "$TRAVIS_OS_NAME" = "osx" ]; then sudo gmake install ; else sudo make install; fi
|
||||
|
||||
jobs:
|
||||
allow_failures:
|
||||
- os: osx
|
||||
# jobs:
|
||||
# allow_failures:
|
||||
# - os: osx
|
||||
|
||||
|
||||
@@ -28,24 +28,27 @@
|
||||
firstTarget: all
|
||||
|
||||
CXX = @CXX@
|
||||
CXXFLAGS = @CXXFLAGS@ @BOOST_CPPFLAGS@ @LIBBZ2_CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@ @LIBS@ @BOOST_LDFLAGS@ @LIBBZ2_LDFLAGS@
|
||||
CXXFLAGS = @CPPFLAGS@ @CXXFLAGS@ @BOOST_CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@ @LIBS@ @BOOST_LDFLAGS@
|
||||
LIBS = @LIBS@ \
|
||||
-latomic \
|
||||
@BOOST_IOSTREAMS_LIB@ \
|
||||
@BOOST_DATE_TIME_LIB@
|
||||
|
||||
prefix = @prefix@
|
||||
prefix = $(DESTDIR)@prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
libdir = @libdir@
|
||||
includedir = @includedir@
|
||||
datarootdir = @datarootdir@
|
||||
datadir = @datadir@
|
||||
docdir = @docdir@
|
||||
pkgconfigdir = $(libdir)/pkgconfig
|
||||
|
||||
CCP4DIR = @CCP4@
|
||||
CLIBD = $(CCP4DIR:%=%/lib/data)
|
||||
|
||||
CACHE_DIR = /var/cache/libcifpp
|
||||
CACHE_DIR = $(DESTDIR)/var/cache/libcifpp
|
||||
CRON_DIR = $(DESTDIR)/etc/cron.weekly
|
||||
|
||||
DEFINES += CACHE_DIR='"$(CACHE_DIR)"'
|
||||
|
||||
@@ -159,6 +162,7 @@ else
|
||||
src/revision.hpp:
|
||||
@ echo 'const char kRevision[] = R"(' > $@
|
||||
@ echo libcifpp-version: $(VERSION) >> $@
|
||||
@ echo Date: $$(date --iso-8601) >> $@
|
||||
@ echo ')";' >> $@
|
||||
|
||||
endif
|
||||
@@ -190,6 +194,7 @@ $(OBJDIR)/%.o: %.cpp | $(OBJDIR)
|
||||
.PHONY: clean
|
||||
clean:
|
||||
rm -rf .libs $(OBJDIR)/* $(LIB_TARGET)
|
||||
rm -f $(TESTS:%=test/%-test)
|
||||
|
||||
.PHONY: distclean
|
||||
distclean: clean
|
||||
@@ -207,7 +212,7 @@ $(1)_OBJECTS = $$(OBJDIR)/$(1)-test.o
|
||||
|
||||
test/$(1)-test: $(LIB_TARGET) $$($(1)_OBJECTS)
|
||||
@ echo ">>> building $(1)-test"
|
||||
$(LIBTOOL) --silent --tag=CXX --mode=link $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $$@ $$($(1)_OBJECTS) -L.libs -lcifpp $(LIBS)
|
||||
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $$@ $$($(1)_OBJECTS) -L.libs -lcifpp $(LIBS)
|
||||
|
||||
.PHONY: $(1)-test
|
||||
$(1)-test: test/$(1)-test
|
||||
@@ -243,13 +248,13 @@ HEADERS = \
|
||||
install: lib
|
||||
install -d $(libdir)
|
||||
$(LIBTOOL) --mode=install install $(LIB_TARGET) $(libdir)
|
||||
install -d $(CACHE_DIR)
|
||||
install -d $(datadir)/libcifpp
|
||||
for d in isomers.txt dictionaries/mmcif_ddl.dic dictionaries/mmcif_pdbx_v50.dic; do \
|
||||
install -m644 rsrc/$$d $(CACHE_DIR)/; \
|
||||
install -m644 rsrc/$$d $(datadir)/libcifpp; \
|
||||
done
|
||||
if [ -d /etc/cron.weekly ]; then \
|
||||
install -m755 tools/update-dictionaries-script /etc/cron.weekly/libcifpp; \
|
||||
fi
|
||||
gzip -f $(datadir)/libcifpp/*
|
||||
install -d $(CRON_DIR)
|
||||
install -m755 tools/update-dictionary-script $(CRON_DIR)/libcifpp
|
||||
install -d $(includedir)/cif++
|
||||
for f in $(HEADERS); do install include/cif++/$$f $(includedir)/cif++/$$f; done
|
||||
install -d $(pkgconfigdir)
|
||||
|
||||
6
changelog
Normal file
6
changelog
Normal file
@@ -0,0 +1,6 @@
|
||||
Version 1.0.1
|
||||
- Changed the way resources are looked up, local dir first,
|
||||
then /var/cache and finally compiled in resources (with mrc).
|
||||
|
||||
Version 1.0.0
|
||||
- First public release
|
||||
209
configure
vendored
209
configure
vendored
@@ -635,10 +635,6 @@ ac_includes_default="\
|
||||
|
||||
ac_subst_vars='LTLIBOBJS
|
||||
LIBOBJS
|
||||
LIBBZ2_LDFLAGS
|
||||
LIBBZ2_CPPFLAGS
|
||||
LIBZ_LDFLAGS
|
||||
LIBZ_CPPFLAGS
|
||||
BOOST_DATE_TIME_LIB
|
||||
BOOST_IOSTREAMS_LIB
|
||||
BOOST_LDFLAGS
|
||||
@@ -647,6 +643,7 @@ SET_MAKE
|
||||
PKG_CONFIG
|
||||
CCP4
|
||||
UPDATE_REVISION
|
||||
USE_RSRC
|
||||
DEBUG
|
||||
LIBCIF_SEMANTIC_VERSION
|
||||
LIBCIF_LT_VERSION
|
||||
@@ -749,6 +746,7 @@ with_aix_soname
|
||||
with_gnu_ld
|
||||
with_sysroot
|
||||
enable_libtool_lock
|
||||
enable_revision
|
||||
with_boost
|
||||
with_boost_libdir
|
||||
with_boost_iostreams
|
||||
@@ -768,12 +766,7 @@ CC
|
||||
CFLAGS
|
||||
LT_SYS_LIBRARY_PATH
|
||||
DEBUG
|
||||
UPDATE_REVISION
|
||||
CCP4
|
||||
LIBZ_CPPFLAGS
|
||||
LIBZ_LDFLAGS
|
||||
LIBBZ2_CPPFLAGS
|
||||
LIBBZ2_LDFLAGS'
|
||||
CCP4'
|
||||
|
||||
|
||||
# Initialize some variables set by options.
|
||||
@@ -1403,6 +1396,7 @@ Optional Features:
|
||||
--enable-fast-install[=PKGS]
|
||||
optimize for fast installation [default=yes]
|
||||
--disable-libtool-lock avoid locking (might break parallel builds)
|
||||
--enable-revision Create a build number as revision
|
||||
|
||||
Optional Packages:
|
||||
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
|
||||
@@ -1449,17 +1443,7 @@ Some influential environment variables:
|
||||
LT_SYS_LIBRARY_PATH
|
||||
User-defined run-time library search path.
|
||||
DEBUG Build a debug version of the library
|
||||
UPDATE_REVISION
|
||||
Update the revision.hpp file
|
||||
CCP4 The location where CCP4 is installed
|
||||
LIBZ_CPPFLAGS
|
||||
C preprocessor flags for LIBZ headers
|
||||
LIBZ_LDFLAGS
|
||||
linker flags for LIBZ libraries
|
||||
LIBBZ2_CPPFLAGS
|
||||
C preprocessor flags for LIBBZ2 headers
|
||||
LIBBZ2_LDFLAGS
|
||||
linker flags for LIBBZ2 libraries
|
||||
|
||||
Use these variables to override the choices made by `configure' or to help
|
||||
it to find libraries and programs with nonstandard names/locations.
|
||||
@@ -16091,6 +16075,28 @@ LIBCIF_SEMANTIC_VERSION=1.0.0
|
||||
|
||||
|
||||
|
||||
# Check whether --enable-revision was given.
|
||||
if test "${enable_revision+set}" = set; then :
|
||||
enableval=$enable_revision;
|
||||
fi
|
||||
|
||||
|
||||
if test "x$enable_revision" != "xyes" ; then :
|
||||
|
||||
UPDATE_REVISION=1
|
||||
|
||||
fi
|
||||
|
||||
case $host in #(
|
||||
*-apple-*) :
|
||||
USE_RSRC=0 ;; #(
|
||||
*) :
|
||||
USE_RSRC=1
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
UPDATE_REVISION=$UPDATE_REVISION
|
||||
|
||||
|
||||
|
||||
@@ -17097,169 +17103,6 @@ fi
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if ${ax_cv_have_LIBZ+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
save_CPPFLAGS="$CPPFLAGS"
|
||||
save_LDFLAGS="$LDFLAGS"
|
||||
save_LIBS="$LIBS"
|
||||
|
||||
if test "x$LIBZ_CPPFLAGS" != "x"; then :
|
||||
CPPFLAGS="$CPPFLAGS $LIBZ_CPPFLAGS"
|
||||
fi
|
||||
|
||||
if test "x$LIBZ_LDFLAGS" != "x"; then :
|
||||
LDFLAGS="$LDFLAGS $LIBZ_LDFLAGS"
|
||||
fi
|
||||
|
||||
ac_fn_cxx_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_zlib_h" = xyes; then :
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lz" >&5
|
||||
$as_echo_n "checking for main in -lz... " >&6; }
|
||||
if ${ac_cv_lib_z_main+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lz $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return main ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_cxx_try_link "$LINENO"; then :
|
||||
ac_cv_lib_z_main=yes
|
||||
else
|
||||
ac_cv_lib_z_main=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_z_main" >&5
|
||||
$as_echo "$ac_cv_lib_z_main" >&6; }
|
||||
if test "x$ac_cv_lib_z_main" = xyes; then :
|
||||
ax_cv_have_LIBZ=yes
|
||||
else
|
||||
ax_cv_have_LIBZ=no
|
||||
fi
|
||||
|
||||
|
||||
else
|
||||
ax_cv_have_LIBZ=no
|
||||
fi
|
||||
|
||||
|
||||
|
||||
CPPFLAGS="$save_CPPFLAGS"
|
||||
LDFLAGS="$save_LDFLAGS"
|
||||
LIBS="$save_LIBS"
|
||||
|
||||
fi
|
||||
|
||||
|
||||
if test "$ax_cv_have_LIBZ" = "yes"; then :
|
||||
|
||||
$as_echo "#define HAVE_LIBZ 1" >>confdefs.h
|
||||
|
||||
|
||||
else
|
||||
as_fn_error $? "libz not found - compressed files not supported" "$LINENO" 5
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
if ${ax_cv_have_LIBBZ2+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
save_CPPFLAGS="$CPPFLAGS"
|
||||
save_LDFLAGS="$LDFLAGS"
|
||||
save_LIBS="$LIBS"
|
||||
|
||||
if test "x$LIBBZ2_CPPFLAGS" != "x"; then :
|
||||
CPPFLAGS="$CPPFLAGS $LIBBZ2_CPPFLAGS"
|
||||
fi
|
||||
|
||||
if test "x$LIBBZ2_LDFLAGS" != "x"; then :
|
||||
LDFLAGS="$LDFLAGS $LIBBZ2_LDFLAGS"
|
||||
fi
|
||||
|
||||
ac_fn_cxx_check_header_mongrel "$LINENO" "bzlib.h" "ac_cv_header_bzlib_h" "$ac_includes_default"
|
||||
if test "x$ac_cv_header_bzlib_h" = xyes; then :
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lbz2" >&5
|
||||
$as_echo_n "checking for main in -lbz2... " >&6; }
|
||||
if ${ac_cv_lib_bz2_main+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-lbz2 $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return main ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_cxx_try_link "$LINENO"; then :
|
||||
ac_cv_lib_bz2_main=yes
|
||||
else
|
||||
ac_cv_lib_bz2_main=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bz2_main" >&5
|
||||
$as_echo "$ac_cv_lib_bz2_main" >&6; }
|
||||
if test "x$ac_cv_lib_bz2_main" = xyes; then :
|
||||
ax_cv_have_LIBBZ2=yes
|
||||
else
|
||||
ax_cv_have_LIBBZ2=no
|
||||
fi
|
||||
|
||||
|
||||
else
|
||||
ax_cv_have_LIBBZ2=no
|
||||
fi
|
||||
|
||||
|
||||
|
||||
CPPFLAGS="$save_CPPFLAGS"
|
||||
LDFLAGS="$save_LDFLAGS"
|
||||
LIBS="$save_LIBS"
|
||||
|
||||
fi
|
||||
|
||||
|
||||
if test "$ax_cv_have_LIBBZ2" = "yes"; then :
|
||||
|
||||
$as_echo "#define HAVE_LIBBZ2 1" >>confdefs.h
|
||||
|
||||
|
||||
else
|
||||
as_fn_error $? "libbz2 not found - compressed files not supported" "$LINENO" 5
|
||||
fi
|
||||
|
||||
|
||||
ac_config_files="$ac_config_files GNUmakefile libcifpp.pc"
|
||||
|
||||
cat >confcache <<\_ACEOF
|
||||
|
||||
23
configure.ac
23
configure.ac
@@ -74,7 +74,23 @@ AC_SUBST(LIBCIF_SEMANTIC_VERSION)
|
||||
|
||||
AC_ARG_VAR([DEBUG], [Build a debug version of the library])
|
||||
|
||||
AC_ARG_VAR([UPDATE_REVISION], [Update the revision.hpp file])
|
||||
dnl revision numbering is something used internally at the NKI
|
||||
AC_ARG_ENABLE(
|
||||
revision,
|
||||
[AS_HELP_STRING([--enable-revision], [Create a build number as revision])])
|
||||
|
||||
AS_IF([test "x$enable_revision" != "xyes" ], [
|
||||
UPDATE_REVISION=1
|
||||
])
|
||||
|
||||
dnl disable resources on macOS
|
||||
AS_CASE([$host],
|
||||
[*-apple-*], [USE_RSRC=0],
|
||||
[USE_RSRC=1]
|
||||
)
|
||||
AC_SUBST([USE_RSRC])
|
||||
|
||||
AC_SUBST([UPDATE_REVISION], [$UPDATE_REVISION])
|
||||
|
||||
AC_ARG_VAR([CCP4], [The location where CCP4 is installed])
|
||||
|
||||
@@ -93,10 +109,5 @@ AX_BOOST_BASE([1.71], [], [
|
||||
AX_BOOST_IOSTREAMS
|
||||
AX_BOOST_DATE_TIME
|
||||
|
||||
AX_CHECK_LIBRARY([LIBZ], [zlib.h], [z], [],
|
||||
[AC_MSG_ERROR([libz not found - compressed files not supported])])
|
||||
AX_CHECK_LIBRARY([LIBBZ2], [bzlib.h], [bz2], [],
|
||||
[AC_MSG_ERROR([libbz2 not found - compressed files not supported])])
|
||||
|
||||
AC_OUTPUT([GNUmakefile
|
||||
libcifpp.pc])
|
||||
|
||||
@@ -33,6 +33,8 @@
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
#include <list>
|
||||
#include <iostream>
|
||||
#include <filesystem>
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
@@ -190,6 +192,11 @@ class Progress
|
||||
struct ProgressImpl* mImpl;
|
||||
};
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// Resources
|
||||
|
||||
std::unique_ptr<std::istream> loadResource(std::filesystem::path name);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -21,12 +21,6 @@
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if LIBBZ2 is found */
|
||||
#undef HAVE_LIBBZ2
|
||||
|
||||
/* Define to 1 if LIBZ is found */
|
||||
#undef HAVE_LIBZ
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ struct SymopData
|
||||
|
||||
friend struct SymopDataBlock;
|
||||
|
||||
const uint64_t kPackMask = (~0UL >> (64-36));
|
||||
const uint64_t kPackMask = (~0ULL >> (64-36));
|
||||
|
||||
SymopData(uint64_t v)
|
||||
: m_packed(v bitand kPackMask) {}
|
||||
|
||||
@@ -3093,39 +3093,16 @@ void File::loadDictionary()
|
||||
|
||||
void File::loadDictionary(const char* dict)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
fs::path name(dict);
|
||||
|
||||
try
|
||||
{
|
||||
if (fs::exists(name))
|
||||
{
|
||||
std::ifstream is(name);
|
||||
loadDictionary(is);
|
||||
break;
|
||||
}
|
||||
}
|
||||
catch (...) {}
|
||||
fs::path dict_name(dict);
|
||||
|
||||
fs::path datadir = CACHE_DIR;
|
||||
|
||||
if (not fs::is_directory(datadir))
|
||||
throw std::runtime_error("Could not find dictionary " + name.string() + " and " CACHE_DIR " also does not exist");
|
||||
auto data = loadResource(dict);
|
||||
if (not data and dict_name.extension().string() != ".dic")
|
||||
data = loadResource(dict_name.parent_path() / (dict_name.filename().string() + ".dic"));
|
||||
|
||||
name = datadir / name;
|
||||
if (not fs::exists(name) and name.extension().string() != ".dic")
|
||||
name = datadir / (name.string() + ".dic");
|
||||
|
||||
if (fs::exists(name))
|
||||
{
|
||||
std::ifstream is(name);
|
||||
loadDictionary(is);
|
||||
break;
|
||||
}
|
||||
|
||||
throw std::runtime_error("Dictionary not found or defined (" + name.string() + ")");
|
||||
}
|
||||
if (not data)
|
||||
throw std::runtime_error("Dictionary not found or defined (" + dict_name.string() + ")");
|
||||
|
||||
loadDictionary(*data);
|
||||
}
|
||||
|
||||
void File::loadDictionary(std::istream& is)
|
||||
|
||||
446
src/CifUtils.cpp
446
src/CifUtils.cpp
@@ -748,3 +748,449 @@ void Progress::message(const std::string& inMessage)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if USE_RSRC
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
//
|
||||
// Try to find a named resource. Can be either a local file with this name,
|
||||
// a file located in our cache directory or a resource linked in with mrc.
|
||||
//
|
||||
// We have a special, private version of mrsrc here. To be able to create
|
||||
// shared libraries and still be able to link when there's no mrc used.
|
||||
|
||||
namespace mrsrc
|
||||
{
|
||||
/// \brief Internal data structure as generated by mrc
|
||||
struct rsrc_imp
|
||||
{
|
||||
unsigned int m_next;
|
||||
unsigned int m_child;
|
||||
unsigned int m_name;
|
||||
unsigned int m_size;
|
||||
unsigned int m_data;
|
||||
};
|
||||
}
|
||||
|
||||
extern const __attribute__((weak)) mrsrc::rsrc_imp gResourceIndex[];
|
||||
extern const __attribute__((weak)) char gResourceData[];
|
||||
extern const __attribute__((weak)) char gResourceName[];
|
||||
|
||||
namespace mrsrc
|
||||
{
|
||||
class rsrc_data
|
||||
{
|
||||
public:
|
||||
static rsrc_data& instance()
|
||||
{
|
||||
static rsrc_data s_instance;
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
const rsrc_imp* index() const { return m_index; }
|
||||
|
||||
const char* data(unsigned int offset) const
|
||||
{
|
||||
return m_data + offset;
|
||||
}
|
||||
|
||||
const char* name(unsigned int offset) const
|
||||
{
|
||||
return m_name + offset;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
rsrc_data()
|
||||
{
|
||||
if (gResourceIndex and gResourceIndex and gResourceName)
|
||||
{
|
||||
m_index = gResourceIndex;
|
||||
m_data = gResourceData;
|
||||
m_name = gResourceName;
|
||||
}
|
||||
}
|
||||
|
||||
rsrc_imp m_dummy = {};
|
||||
const rsrc_imp* m_index = &m_dummy;
|
||||
const char* m_data = "";
|
||||
const char* m_name = "";
|
||||
};
|
||||
|
||||
/// \brief Class mrsrc::rsrc contains a pointer to the data in the
|
||||
/// resource, as well as offering an iterator interface to its
|
||||
/// children.
|
||||
|
||||
class rsrc
|
||||
{
|
||||
public:
|
||||
|
||||
rsrc() : m_impl(rsrc_data::instance().index()) {}
|
||||
|
||||
rsrc(const rsrc& other)
|
||||
: m_impl(other.m_impl) {}
|
||||
|
||||
rsrc& operator=(const rsrc& other)
|
||||
{
|
||||
m_impl = other.m_impl;
|
||||
return *this;
|
||||
}
|
||||
|
||||
rsrc(std::filesystem::path path);
|
||||
|
||||
std::string name() const { return rsrc_data::instance().name(m_impl->m_name); }
|
||||
|
||||
const char* data() const { return rsrc_data::instance().data(m_impl->m_data); }
|
||||
|
||||
unsigned long size() const { return m_impl->m_size; }
|
||||
|
||||
explicit operator bool() const { return m_impl != NULL and m_impl->m_size > 0; }
|
||||
|
||||
template<typename RSRC>
|
||||
class iterator_t
|
||||
{
|
||||
public:
|
||||
|
||||
using iterator_category = std::input_iterator_tag;
|
||||
using value_type = RSRC;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
|
||||
iterator_t(const rsrc_imp* cur)
|
||||
: m_cur(cur) {}
|
||||
|
||||
iterator_t(const iterator_t& i)
|
||||
: m_cur(i.m_cur)
|
||||
{
|
||||
}
|
||||
|
||||
iterator_t& operator=(const iterator_t& i)
|
||||
{
|
||||
m_cur = i.m_cur;
|
||||
return *this;
|
||||
}
|
||||
|
||||
reference operator*() { return m_cur; }
|
||||
pointer operator->() { return& m_cur; }
|
||||
|
||||
iterator_t& operator++()
|
||||
{
|
||||
if (m_cur.m_impl->m_next)
|
||||
m_cur.m_impl = rsrc_data::instance().index() + m_cur.m_impl->m_next;
|
||||
else
|
||||
m_cur.m_impl = nullptr;
|
||||
return *this;
|
||||
}
|
||||
|
||||
iterator_t operator++(int)
|
||||
{
|
||||
auto tmp(*this);
|
||||
this->operator++();
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool operator==(const iterator_t& rhs) const { return m_cur.m_impl == rhs.m_cur.m_impl; }
|
||||
bool operator!=(const iterator_t& rhs) const { return m_cur.m_impl != rhs.m_cur.m_impl; }
|
||||
|
||||
private:
|
||||
value_type m_cur;
|
||||
};
|
||||
|
||||
using iterator = iterator_t<rsrc>;
|
||||
|
||||
iterator begin() const
|
||||
{
|
||||
const rsrc_imp* impl = nullptr;
|
||||
if (m_impl and m_impl->m_child)
|
||||
impl = rsrc_data::instance().index() + m_impl->m_child;
|
||||
return iterator(impl);
|
||||
}
|
||||
|
||||
iterator end() const
|
||||
{
|
||||
return iterator(nullptr);
|
||||
}
|
||||
|
||||
private:
|
||||
rsrc(const rsrc_imp* imp)
|
||||
: m_impl(imp) {}
|
||||
|
||||
const rsrc_imp *m_impl;
|
||||
};
|
||||
|
||||
inline rsrc::rsrc(std::filesystem::path p)
|
||||
{
|
||||
m_impl = rsrc_data::instance().index();
|
||||
|
||||
// using std::filesytem::path would have been natural here of course...
|
||||
|
||||
auto pb = p.begin();
|
||||
auto pe = p.end();
|
||||
|
||||
while (m_impl != nullptr and pb != pe)
|
||||
{
|
||||
auto name = *pb++;
|
||||
|
||||
const rsrc_imp* impl = nullptr;
|
||||
for (rsrc child: *this)
|
||||
{
|
||||
if (child.name() == name)
|
||||
{
|
||||
impl = child.m_impl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
m_impl = impl;
|
||||
}
|
||||
|
||||
if (pb != pe) // not found
|
||||
m_impl = nullptr;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
class basic_streambuf : public std::basic_streambuf<CharT, Traits>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef CharT char_type;
|
||||
typedef Traits traits_type;
|
||||
typedef typename traits_type::int_type int_type;
|
||||
typedef typename traits_type::pos_type pos_type;
|
||||
typedef typename traits_type::off_type off_type;
|
||||
|
||||
/// \brief constructor taking a \a path to the resource in memory
|
||||
basic_streambuf(const std::string& path)
|
||||
: m_rsrc(path)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
/// \brief constructor taking a \a rsrc
|
||||
basic_streambuf(const rsrc& rsrc)
|
||||
: m_rsrc(rsrc)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
basic_streambuf(const basic_streambuf&) = delete;
|
||||
|
||||
basic_streambuf(basic_streambuf&& rhs)
|
||||
: basic_streambuf(rhs.m_rsrc)
|
||||
{
|
||||
}
|
||||
|
||||
basic_streambuf& operator=(const basic_streambuf&) = delete;
|
||||
|
||||
basic_streambuf& operator=(basic_streambuf&& rhs)
|
||||
{
|
||||
swap(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(basic_streambuf& rhs)
|
||||
{
|
||||
std::swap(m_begin, rhs.m_begin);
|
||||
std::swap(m_end, rhs.m_end);
|
||||
std::swap(m_current, rhs.m_current);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void init()
|
||||
{
|
||||
m_begin = reinterpret_cast<const char_type*>(m_rsrc.data());
|
||||
m_end = reinterpret_cast<const char_type*>(m_rsrc.data() + m_rsrc.size());
|
||||
m_current = m_begin;
|
||||
}
|
||||
|
||||
int_type underflow()
|
||||
{
|
||||
if (m_current == m_end)
|
||||
return traits_type::eof();
|
||||
|
||||
return traits_type::to_int_type(*m_current);
|
||||
}
|
||||
|
||||
int_type uflow()
|
||||
{
|
||||
if (m_current == m_end)
|
||||
return traits_type::eof();
|
||||
|
||||
return traits_type::to_int_type(*m_current++);
|
||||
}
|
||||
|
||||
int_type pbackfail(int_type ch)
|
||||
{
|
||||
if (m_current == m_begin or (ch != traits_type::eof() and ch != m_current[-1]))
|
||||
return traits_type::eof();
|
||||
|
||||
return traits_type::to_int_type(*--m_current);
|
||||
}
|
||||
|
||||
std::streamsize showmanyc()
|
||||
{
|
||||
assert(std::less_equal<const char*>()(m_current, m_end));
|
||||
return m_end - m_current;
|
||||
}
|
||||
|
||||
pos_type seekoff(off_type off, std::ios_base::seekdir dir, std::ios_base::openmode which)
|
||||
{
|
||||
switch (dir)
|
||||
{
|
||||
case std::ios_base::beg:
|
||||
m_current = m_begin + off;
|
||||
break;
|
||||
|
||||
case std::ios_base::end:
|
||||
m_current = m_end + off;
|
||||
break;
|
||||
|
||||
case std::ios_base::cur:
|
||||
m_current += off;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_current < m_begin)
|
||||
m_current = m_begin;
|
||||
|
||||
if (m_current > m_end)
|
||||
m_current = m_end;
|
||||
|
||||
return m_current - m_begin;
|
||||
}
|
||||
|
||||
pos_type seekpos(pos_type pos, std::ios_base::openmode which)
|
||||
{
|
||||
m_current = m_begin + pos;
|
||||
|
||||
if (m_current < m_begin)
|
||||
m_current = m_begin;
|
||||
|
||||
if (m_current > m_end)
|
||||
m_current = m_end;
|
||||
|
||||
return m_current - m_begin;
|
||||
}
|
||||
|
||||
private:
|
||||
rsrc m_rsrc;
|
||||
const char_type* m_begin;
|
||||
const char_type* m_end;
|
||||
const char_type* m_current;
|
||||
};
|
||||
|
||||
using streambuf = basic_streambuf<char, std::char_traits<char>>;
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// class mrsrc::istream
|
||||
|
||||
template<typename CharT, typename Traits>
|
||||
class basic_istream : public std::basic_istream<CharT, Traits>
|
||||
{
|
||||
public:
|
||||
typedef CharT char_type;
|
||||
typedef Traits traits_type;
|
||||
typedef typename traits_type::int_type int_type;
|
||||
typedef typename traits_type::pos_type pos_type;
|
||||
typedef typename traits_type::off_type off_type;
|
||||
|
||||
private:
|
||||
|
||||
using __streambuf_type = basic_streambuf<CharT, Traits>;
|
||||
using __istream_type = std::basic_istream<CharT, Traits>;
|
||||
|
||||
__streambuf_type m_buffer;
|
||||
|
||||
public:
|
||||
|
||||
basic_istream(const std::string& path)
|
||||
: __istream_type(&m_buffer)
|
||||
, m_buffer(path)
|
||||
{
|
||||
this->init(&m_buffer);
|
||||
}
|
||||
|
||||
basic_istream(rsrc& resource)
|
||||
: __istream_type(&m_buffer)
|
||||
, m_buffer(resource)\
|
||||
{
|
||||
this->init(&m_buffer);
|
||||
}
|
||||
|
||||
basic_istream(const basic_istream&) = delete;
|
||||
|
||||
basic_istream(basic_istream&& rhs)
|
||||
: __istream_type(std::move(rhs))
|
||||
, m_buffer(std::move(rhs.m_buffer))
|
||||
{
|
||||
__istream_type::set_rdbuf(&m_buffer);
|
||||
}
|
||||
|
||||
basic_istream& operator=(const basic_istream& ) = delete;
|
||||
|
||||
basic_istream& operator=(basic_istream&& rhs)
|
||||
{
|
||||
__istream_type::operator=(std::move(rhs));
|
||||
m_buffer = std::move(rhs.m_buffer);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(basic_istream& rhs)
|
||||
{
|
||||
__istream_type::swap(rhs);
|
||||
m_buffer.swap(rhs.m_buffer);
|
||||
}
|
||||
|
||||
__streambuf_type* rdbuf() const
|
||||
{
|
||||
return const_cast<__streambuf_type*>(&m_buffer);
|
||||
}
|
||||
};
|
||||
|
||||
using istream = basic_istream<char, std::char_traits<char>>;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
namespace cif
|
||||
{
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
std::unique_ptr<std::istream> loadResource(std::filesystem::path name)
|
||||
{
|
||||
std::unique_ptr<std::istream> result;
|
||||
|
||||
fs::path p = name;
|
||||
if (not fs::exists(p))
|
||||
p = fs::path(CACHE_DIR) / p;
|
||||
|
||||
if (fs::exists(p))
|
||||
{
|
||||
std::unique_ptr<std::ifstream> file(new std::ifstream(p));
|
||||
if (file->is_open())
|
||||
result.reset(file.release());
|
||||
}
|
||||
|
||||
#if USE_RSRC
|
||||
if (not result)
|
||||
{
|
||||
mrsrc::rsrc rsrc(name);
|
||||
if (rsrc)
|
||||
result.reset(new mrsrc::istream(rsrc));
|
||||
}
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -2,6 +2,11 @@
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$EUID" -ne 0 ]
|
||||
then echo "Please run as root"
|
||||
exit
|
||||
fi
|
||||
|
||||
# create cache directory if it doesn't exist
|
||||
if ! [ -d /var/cache/libcifpp ]; then
|
||||
install -d -m755 /var/cache/libcifpp
|
||||
Reference in New Issue
Block a user