diff --git a/acinclude.m4 b/acinclude.m4 index 121a3380..685209d4 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -10,6 +10,71 @@ dnl but WITHOUT ANY WARRANTY; without even the implied warranty of dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the dnl GNU General Public License for more details. +AC_DEFUN([ACX_CHECK_CXX_BOOL], [ + AC_MSG_CHECKING([for bool support]) + AC_TRY_COMPILE(, [bool t = true, f = false;],[acx_cxx_bool_ok=yes]) + AC_MSG_RESULT($acx_cxx_bool_ok) + if test x"$acx_cxx_bool_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_CXX_BOOL,1,[Define if your compiler has bool support.]),[$1]) + : + else + acx_cxx_bool_ok=no + $2 + fi +])dnl ACX_CHECK_BOOL + +AC_DEFUN([ACX_CHECK_CXX_EXCEPTIONS], [ + AC_MSG_CHECKING([for exception support]) + AC_TRY_COMPILE(, [try{throw int(4);}catch(int){throw;}catch(...){}],[acx_cxx_exception_ok=yes]) + AC_MSG_RESULT($acx_cxx_exception_ok) + if test x"$acx_cxx_exception_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_CXX_EXCEPTIONS,1,[Define if your compiler has exceptions support.]),[$1]) + : + else + acx_cxx_exception_ok=no + $2 + fi +])dnl ACX_CHECK_CXX_EXCEPTIONS + +AC_DEFUN([ACX_CHECK_CXX_CASTS], [ + AC_MSG_CHECKING([for C++ cast support]) + AC_TRY_COMPILE(, [const char* f="a";const_cast(f);reinterpret_cast(f);static_cast(4.5);],[acx_cxx_cast_ok=yes]) + AC_MSG_RESULT($acx_cxx_cast_ok) + if test x"$acx_cxx_cast_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_CXX_CASTS,1,[Define if your compiler has C++ cast support.]),[$1]) + : + else + acx_cxx_cast_ok=no + $2 + fi +])dnl ACX_CHECK_CXX_CASTS + +AC_DEFUN([ACX_CHECK_CXX_MUTABLE], [ + AC_MSG_CHECKING([for mutable support]) + AC_TRY_COMPILE(, [struct A{mutable int b;void f() const {b=0;}};A a;a.f();],[acx_cxx_mutable_ok=yes]) + AC_MSG_RESULT($acx_cxx_mutable_ok) + if test x"$acx_cxx_mutable_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_CXX_MUTABLE,1,[Define if your compiler has mutable support.]),[$1]) + : + else + acx_cxx_mutable_ok=no + $2 + fi +])dnl ACX_CHECK_CXX_MUTABLE + +AC_DEFUN([ACX_CHECK_CXX_STDLIB], [ + AC_MSG_CHECKING([for C++ standard library]) + AC_TRY_LINK([#include ], [std::set a; a.insert(3);],[acx_cxx_stdlib_ok=yes]) + AC_MSG_RESULT($acx_cxx_stdlib_ok) + if test x"$acx_cxx_stdlib_ok" = xyes; then + ifelse([$1],,AC_DEFINE(HAVE_CXX_STDLIB,1,[Define if your compiler has standard C++ library support.]),[$1]) + : + else + acx_cxx_stdlib_ok=no + $2 + fi +])dnl ACX_CHECK_CXX_STDLIB + dnl The following macros are from http://www.gnu.org/software/ac-archive/ dnl which distributes them under the following license: dnl diff --git a/configure.in b/configure.in index 3fe32f27..f32f01d0 100644 --- a/configure.in +++ b/configure.in @@ -34,10 +34,13 @@ AC_PROG_RANLIB dnl checks for libraries ACX_PTHREAD(,AC_MSG_ERROR(You must have pthreads to compile synergy)) +dnl do checks using C++ +AC_LANG(C++) + dnl checks for header files AC_HEADER_STDC AC_CHECK_HEADERS([unistd.h sys/time.h]) -AC_CHECK_HEADERS([istream ostream]) +AC_CHECK_HEADERS([istream ostream sstream]) AC_CHECK_HEADERS([windows.h]) AC_HEADER_TIME AC_PATH_X @@ -45,7 +48,7 @@ AC_PATH_XTRA AC_CHECK_HEADERS([X11/extensions/XTest.h]) dnl checks for types -dnl AC_TYPE_SIZE_T +AC_TYPE_SIZE_T dnl checks for structures AC_STRUCT_TM @@ -55,11 +58,11 @@ AC_CHECK_SIZEOF(char, 1) AC_CHECK_SIZEOF(short, 2) AC_CHECK_SIZEOF(int, 2) AC_CHECK_SIZEOF(long, 4) -dnl require bool support -dnl require template support -dnl require exception support -dnl require C++ casting support -dnl require mutable support +ACX_CHECK_CXX_BOOL(,AC_MSG_ERROR(Your compiler must support bool to compile synergy)) +ACX_CHECK_CXX_EXCEPTIONS(,AC_MSG_ERROR(Your compiler must support exceptions to compile synergy)) +ACX_CHECK_CXX_CASTS(,AC_MSG_ERROR(Your compiler must support C++ casts to compile synergy)) +ACX_CHECK_CXX_MUTABLE(,AC_MSG_ERROR(Your compiler must support mutable to compile synergy)) +ACX_CHECK_CXX_STDLIB(,AC_MSG_ERROR(Your compiler must support the C++ standard library to compile synergy)) dnl checks for library functions dnl AC_TYPE_SIGNAL diff --git a/lib/base/stdsstream.h b/lib/base/stdsstream.h index 1bd2b970..ed8e723f 100644 --- a/lib/base/stdsstream.h +++ b/lib/base/stdsstream.h @@ -13,6 +13,359 @@ */ #include "stdpre.h" + +#if defined(HAVE_SSTREAM) || !defined(__GNUC__) || (__GNUC__ >= 3) + #include + +#elif defined(__GNUC_MINOR__) && (__GNUC_MINOR__ >= 95) +// g++ 2.95 didn't ship with sstream. the following is a backport +// by Magnus Fromreide of the sstream in g++ 3.0. + +/* This is part of libio/iostream, providing -*- C++ -*- input/output. +Copyright (C) 2000 Free Software Foundation + +This file is part of the GNU IO Library. This library 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, or (at your option) +any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this library; see the file COPYING. If not, write to the Free +Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +As a special exception, if you link this library with files +compiled with a GNU compiler to produce an executable, this does not cause +the resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why +the executable file might be covered by the GNU General Public License. */ + +/* Written by Magnus Fromreide (magfr@lysator.liu.se). */ +/* seekoff and ideas for overflow is largely borrowed from libstdc++-v3 */ + +#include +#include +#include + +namespace std +{ + class stringbuf : public streambuf + { + public: + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; + + explicit + stringbuf(int which=ios::in|ios::out) + : streambuf(), mode(static_cast(which)), + stream(NULL), stream_len(0) + { + stringbuf_init(); + } + + explicit + stringbuf(const string &str, int which=ios::in|ios::out) + : streambuf(), mode(static_cast(which)), + stream(NULL), stream_len(0) + { + if (mode & (ios::in|ios::out)) + { + stream_len = str.size(); + stream = new char_type[stream_len]; + str.copy(stream, stream_len); + } + stringbuf_init(); + } + + virtual + ~stringbuf() + { + delete[] stream; + } + + string + str() const + { + if (pbase() != 0) + return string(stream, pptr()-pbase()); + else + return string(); + } + + void + str(const string& str) + { + delete[] stream; + stream_len = str.size(); + stream = new char_type[stream_len]; + str.copy(stream, stream_len); + stringbuf_init(); + } + + protected: + // The buffer is already in gptr, so if it ends then it is out of data. + virtual int + underflow() + { + return EOF; + } + + virtual int + overflow(int c = EOF) + { + int res; + if (mode & ios::out) + { + if (c != EOF) + { + streamsize old_stream_len = stream_len; + stream_len += 1; + char_type* new_stream = new char_type[stream_len]; + memcpy(new_stream, stream, old_stream_len); + delete[] stream; + stream = new_stream; + stringbuf_sync(gptr()-eback(), pptr()-pbase()); + sputc(c); + res = c; + } + else + res = EOF; + } + else + res = 0; + return res; + } + + virtual streambuf* + setbuf(char_type* s, streamsize n) + { + if (n != 0) + { + delete[] stream; + stream = new char_type[n]; + memcpy(stream, s, n); + stream_len = n; + stringbuf_sync(0, 0); + } + return this; + } + + virtual pos_type + seekoff(off_type off, ios::seek_dir way, int which = ios::in | ios::out) + { + pos_type ret = pos_type(off_type(-1)); + bool testin = which & ios::in && mode & ios::in; + bool testout = which & ios::out && mode & ios::out; + bool testboth = testin && testout && way != ios::cur; + + if (stream_len && ((testin != testout) || testboth)) + { + char_type* beg = stream; + char_type* curi = NULL; + char_type* curo = NULL; + char_type* endi = NULL; + char_type* endo = NULL; + + if (testin) + { + curi = gptr(); + endi = egptr(); + } + if (testout) + { + curo = pptr(); + endo = epptr(); + } + + off_type newoffi = 0; + off_type newoffo = 0; + if (way == ios::beg) + { + newoffi = beg - curi; + newoffo = beg - curo; + } + else if (way == ios::end) + { + newoffi = endi - curi; + newoffo = endo - curo; + } + + if (testin && newoffi + off + curi - beg >= 0 && + endi - beg >= newoffi + off + curi - beg) + { + gbump(newoffi + off); + ret = pos_type(newoffi + off + curi); + } + if (testout && newoffo + off + curo - beg >= 0 && + endo - beg >= newoffo + off + curo - beg) + { + pbump(newoffo + off); + ret = pos_type(newoffo + off + curo); + } + } + return ret; + } + + virtual pos_type + seekpos(pos_type sp, int which = ios::in | ios::out) + { + pos_type ret = seekoff(sp, ios::beg, which); + return ret; + } + + private: + void + stringbuf_sync(streamsize i, streamsize o) + { + if (mode & ios::in) + setg(stream, stream + i, stream + stream_len); + if (mode & ios::out) + { + setp(stream, stream + stream_len); + pbump(o); + } + } + void + stringbuf_init() + { + if (mode & ios::ate) + stringbuf_sync(0, stream_len); + else + stringbuf_sync(0, 0); + } + + private: + ios::open_mode mode; + char_type* stream; + streamsize stream_len; + }; + + class istringstream : public istream { + public: + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; + + explicit + istringstream(int which=ios::in) + : istream(&sb), sb(which | ios::in) + { } + + explicit + istringstream(const string& str, int which=ios::in) + : istream(&sb), sb(str, which | ios::in) + { } + + stringbuf* + rdbuf() const + { + return const_cast(&sb); + } + + string + str() const + { + return rdbuf()->str(); + } + void + str(const string& s) + { + rdbuf()->str(s); + } + private: + stringbuf sb; + }; + + class ostringstream : public ostream { + public: + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; + + explicit + ostringstream(int which=ios::out) + : ostream(&sb), sb(which | ios::out) + { } + + explicit + ostringstream(const string& str, int which=ios::out) + : ostream(&sb), sb(str, which | ios::out) + { } + + stringbuf* + rdbuf() const + { + return const_cast(&sb); + } + + string + str() const + { + return rdbuf()->str(); + } + + void str(const string& s) + { + rdbuf()->str(s); + } + private: + stringbuf sb; + }; + + class stringstream : public iostream { + public: + typedef char char_type; + typedef int int_type; + typedef streampos pos_type; + typedef streamoff off_type; + + explicit + stringstream(int which=ios::out|ios::in) + : iostream(&sb), sb(which) + { } + + explicit + stringstream(const string& str, int which=ios::out|ios::in) + : iostream(&sb), sb(str, which) + { } + + stringbuf* + rdbuf() const + { + return const_cast(&sb); + } + + string + str() const + { + return rdbuf()->str(); + } + + void + str(const string& s) + { + rdbuf()->str(s); + } + private: + stringbuf sb; + }; +}; + +#else /* not g++ 2.95 and no */ + +#error "Standard C++ library is missing required sstream header." + +#endif /* not g++ 2.95 and no */ + #include "stdpost.h" #include "stdistream.h"