diff options
| author | Marius Kintel <marius@kintel.net> | 2013-02-07 18:43:20 (GMT) | 
|---|---|---|
| committer | Marius Kintel <marius@kintel.net> | 2013-02-07 18:43:20 (GMT) | 
| commit | 4e519078d60a92fce4c30b7d60b5b3e26181090f (patch) | |
| tree | 4c47cfeee7c60f942442e83811b9b05929fd3fe5 | |
| parent | b911a3615e7c28f3448ca73d7f48a263a568c00c (diff) | |
| parent | 03be37d16b585e64de87118053206aaae06e7cf8 (diff) | |
Merge branch 'master' into issue11_2
| -rw-r--r-- | RELEASE_NOTES | 14 | ||||
| -rw-r--r-- | scripts/setenv-unibuild.sh | 7 | ||||
| -rwxr-xr-x | scripts/uni-build-dependencies.sh | 107 | ||||
| -rw-r--r-- | src/control.cc | 6 | ||||
| -rw-r--r-- | src/csgtermnormalizer.cc | 9 | ||||
| -rw-r--r-- | src/csgtermnormalizer.h | 1 | ||||
| -rw-r--r-- | src/import.cc | 80 | ||||
| -rw-r--r-- | testdata/scad/bugs/issue267-normalization-crash.scad | 86 | ||||
| -rw-r--r-- | tests/CMakeLists.txt | 14 | ||||
| -rw-r--r-- | tests/CTestCustom.template | 13 | ||||
| -rwxr-xr-x | tests/test_cmdline_tool.py | 2 | ||||
| -rw-r--r-- | tests/test_pretty_print.cc | 24 | ||||
| -rwxr-xr-x | tests/virtualfb.sh | 74 | 
13 files changed, 369 insertions, 68 deletions
| diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 4448e89..1e0a737 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -1,3 +1,17 @@ +OpenSCAD 2013.XX +================ + +Features: +o Console output is now enabled on Windows through the openscad.com executable +o Added basic syntax highlighting in the editor + +Bugfixes: +o OpenCSG rendering sometimes crashed when rendering large models +o We didn't always print a warning when CSG normalization created too many elements +o Binary STLs can now be read on big endian architectures +o Some binary STLs couldn't be read +o Fixed some issues related to ARM builds +  OpenSCAD 2013.01  ================ diff --git a/scripts/setenv-unibuild.sh b/scripts/setenv-unibuild.sh index 881526e..66fb7a9 100644 --- a/scripts/setenv-unibuild.sh +++ b/scripts/setenv-unibuild.sh @@ -130,5 +130,12 @@ if [ "`echo $* | grep qt5`" ]; then   setenv_qt5  fi +if [ -e $DEPLOYDIR/include/Qt ]; then +  echo "Qt found under $DEPLOYDIR ... " +  QTDIR=$DEPLOYDIR +  export QTDIR +  echo "QTDIR modified to $DEPLOYDIR" +fi +  clean_note diff --git a/scripts/uni-build-dependencies.sh b/scripts/uni-build-dependencies.sh index 3da11ec..09b6b79 100755 --- a/scripts/uni-build-dependencies.sh +++ b/scripts/uni-build-dependencies.sh @@ -24,14 +24,25 @@  #  # Prerequisites:  # - wget or curl -# - Qt4 +# - OpenGL (GL/gl.h) +# - GLU (GL/glu.h)  # - gcc +# - Qt4 +# +# If your system lacks qt4, build like this: +# +#   ./scripts/uni-build-dependencies.sh qt4 +#   . ./scripts/setenv-unibuild.sh  # -# Enable Clang (experimental, only works on linux): +# If your system lacks glu, try to build like this: +# +#   ./scripts/uni-build-dependencies.sh glu +# +# If you want to try Clang compiler (experimental, only works on linux):  #  #   . ./scripts/setenv-unibuild.sh clang  # -# Enable Qt5 (experimental) +# If you want to try Qt5 (experimental)  #  #   . ./scripts/setenv-unibuild.sh qt5  # @@ -42,6 +53,51 @@ printUsage()    echo  } +build_glu() +{ +  version=$1 +  if [ -e $DEPLOYDIR/lib/libGLU.so ]; then +    echo "GLU already installed. not building" +    return +  fi +  echo "Building GLU" $version "..." +  cd $BASEDIR/src +  rm -rf glu-$version +  if [ ! -f glu-$version.tar.gz ]; then +    curl -O http://cgit.freedesktop.org/mesa/glu/snapshot/glu-$version.tar.gz +  fi +  tar xzf glu-$version.tar.gz +  cd glu-$version +  ./autogen.sh --prefix=$DEPLOYDIR +  make -j$NUMCPU +  make install +} + +build_qt4() +{ +  version=$1 +  if [ -e $DEPLOYDIR/include/Qt ]; then +    echo "qt already installed. not building" +    return +  fi +  echo "Building Qt" $version "..." +  cd $BASEDIR/src +  rm -rf qt-everywhere-opensource-src-$version +  if [ ! -f qt-everywhere-opensource-src-$version.tar.gz ]; then +    curl -O http://releases.qt-project.org/qt4/source/qt-everywhere-opensource-src-$version.tar.gz +  fi +  tar xzf qt-everywhere-opensource-src-$version.tar.gz +  cd qt-everywhere-opensource-src-$version +  ./configure -prefix $DEPLOYDIR -opensource -confirm-license -fast -no-qt3support -no-svg -no-phonon -no-audio-backend -no-multimedia -no-javascript-jit -no-script -no-scripttools -no-declarative -no-xmlpatterns -nomake demos -nomake examples -nomake docs -nomake translations -no-webkit +  make -j$NUMCPU +  make install +  QTDIR=$DEPLOYDIR +  export QTDIR +  echo "----------" +  echo " Please set QTDIR to $DEPLOYDIR ( or run '. scripts/setenv-unibuild.sh' )" +  echo "----------" +} +  build_bison()  {    version=$1 @@ -196,7 +252,12 @@ build_boost()      fi    else      $BJAMBIN -j$NUMCPU -    $BJAMBIN install +    if [ $? = 0 ]; then +      $BJAMBIN install +    else +      echo boost build failed +      exit 1 +    fi    fi  } @@ -211,19 +272,28 @@ build_cgal()    cd $BASEDIR/src    rm -rf CGAL-$version    if [ ! -f CGAL-$version.tar.* ]; then -    #4.0.2 -    curl --insecure -O https://gforge.inria.fr/frs/download.php/31174/CGAL-$version.tar.bz2 -    # 4.0 curl --insecure -O https://gforge.inria.fr/frs/download.php/30387/CGAL-$version.tar.gz -    # 3.9 curl --insecure -O https://gforge.inria.fr/frs/download.php/29125/CGAL-$version.tar.gz +    # 4.1 +    curl --insecure -O https://gforge.inria.fr/frs/download.php/31640/CGAL-$version.tar.bz2 +    # 4.0.2 curl --insecure -O https://gforge.inria.fr/frs/download.php/31174/CGAL-$version.tar.bz2 +    # 4.0 curl --insecure -O https://gforge.inria.fr/frs/download.php/30387/CGAL-$version.tar.gz #4.0 +    # 3.9 curl --insecure -O https://gforge.inria.fr/frs/download.php/29125/CGAL-$version.tar.gz #3.9      # 3.8 curl --insecure -O https://gforge.inria.fr/frs/download.php/28500/CGAL-$version.tar.gz      # 3.7 curl --insecure -O https://gforge.inria.fr/frs/download.php/27641/CGAL-$version.tar.gz    fi -  tar jxf CGAL-$version.tar.bz2 +  tar xf CGAL-$version.tar.bz2    cd CGAL-$version +  mkdir bin +  cd bin +  rm -rf ./* +  if [ "`uname -a| grep ppc64`" ]; then +    CGAL_BUILDTYPE="Release" # avoid assertion violation +  else +    CGAL_BUILDTYPE="Debug" +  fi    if [ "`echo $2 | grep use-sys-libs`" ]; then -    cmake -DCMAKE_INSTALL_PREFIX=$DEPLOYDIR -DWITH_CGAL_Qt3=OFF -DWITH_CGAL_Qt4=OFF -DWITH_CGAL_ImageIO=OFF -DCMAKE_BUILD_TYPE=Debug +    cmake -DCMAKE_INSTALL_PREFIX=$DEPLOYDIR -DWITH_CGAL_Qt3=OFF -DWITH_CGAL_Qt4=OFF -DWITH_CGAL_ImageIO=OFF -DCMAKE_BUILD_TYPE=$CGAL_BUILDTYPE ..    else -    cmake -DCMAKE_INSTALL_PREFIX=$DEPLOYDIR -DGMP_INCLUDE_DIR=$DEPLOYDIR/include -DGMP_LIBRARIES=$DEPLOYDIR/lib/libgmp.so -DGMPXX_LIBRARIES=$DEPLOYDIR/lib/libgmpxx.so -DGMPXX_INCLUDE_DIR=$DEPLOYDIR/include -DMPFR_INCLUDE_DIR=$DEPLOYDIR/include -DMPFR_LIBRARIES=$DEPLOYDIR/lib/libmpfr.so -DWITH_CGAL_Qt3=OFF -DWITH_CGAL_Qt4=OFF -DWITH_CGAL_ImageIO=OFF -DBOOST_ROOT=$DEPLOYDIR -DCMAKE_BUILD_TYPE=Debug +    cmake -DCMAKE_INSTALL_PREFIX=$DEPLOYDIR -DGMP_INCLUDE_DIR=$DEPLOYDIR/include -DGMP_LIBRARIES=$DEPLOYDIR/lib/libgmp.so -DGMPXX_LIBRARIES=$DEPLOYDIR/lib/libgmpxx.so -DGMPXX_INCLUDE_DIR=$DEPLOYDIR/include -DMPFR_INCLUDE_DIR=$DEPLOYDIR/include -DMPFR_LIBRARIES=$DEPLOYDIR/lib/libmpfr.so -DWITH_CGAL_Qt3=OFF -DWITH_CGAL_Qt4=OFF -DWITH_CGAL_ImageIO=OFF -DBOOST_ROOT=$DEPLOYDIR -DCMAKE_BUILD_TYPE=$CGAL_BUILD_TYPE ..    fi    make -j$NUMCPU    make install @@ -284,7 +354,7 @@ build_glew()  build_opencsg()  { -  if [ -e $DEPLOYDIR/include/opencsg.h ]; then +  if [ -e $DEPLOYDIR/lib/libopencsg.so ]; then      echo "OpenCSG already installed. not building"      return    fi @@ -438,6 +508,16 @@ if [ $1 ]; then      build_opencsg 1.3.2      exit    fi +  if [ $1 == "qt4" ]; then +    # such a huge build, put here by itself +    build_qt4 4.8.4 +    exit +  fi +  if [ $1 == "glu" ]; then +    # Mesa and GLU split in late 2012, so it's not on some systems +    build_glu 9.0.0 +    exit +  fi  fi @@ -445,13 +525,12 @@ fi  # Main build of libraries  # edit version numbers here as needed.  # -  build_eigen 3.1.1  build_gmp 5.0.5  build_mpfr 3.1.1  build_boost 1.49.0  # NB! For CGAL, also update the actual download URL in the function -build_cgal 4.0.2 +build_cgal 4.1  build_glew 1.9.0  build_opencsg 1.3.2 diff --git a/src/control.cc b/src/control.cc index bdd0f40..44847f5 100644 --- a/src/control.cc +++ b/src/control.cc @@ -96,8 +96,10 @@ AbstractNode *ControlModule::evaluate(const Context*, const ModuleInstantiation  		size_t n = 0;  		if (inst->argvalues.size() > 0) {  			double v; -			if (inst->argvalues[0].getDouble(v)) -				n = v; +			if (inst->argvalues[0].getDouble(v)) { +				if (v < 0) return NULL; // Disallow negative child indices +				n = trunc(v); +			}  		}  		for (int i = Context::ctx_stack.size()-1; i >= 0; i--) {  			const Context *c = Context::ctx_stack[i]; diff --git a/src/csgtermnormalizer.cc b/src/csgtermnormalizer.cc index e2474e9..461e965 100644 --- a/src/csgtermnormalizer.cc +++ b/src/csgtermnormalizer.cc @@ -7,6 +7,7 @@  */  shared_ptr<CSGTerm> CSGTermNormalizer::normalize(const shared_ptr<CSGTerm> &root)  { +	this->aborted = false;  	shared_ptr<CSGTerm> temp = root;  	while (1) {  		this->rootnode = temp; @@ -20,7 +21,7 @@ shared_ptr<CSGTerm> CSGTermNormalizer::normalize(const shared_ptr<CSGTerm> &root  			PRINTB("WARNING: Normalized tree is growing past %d elements. Aborting normalization.\n", this->limit);        // Clean up any partially evaluated terms  			shared_ptr<CSGTerm> newroot = root, tmproot; -			while (newroot != tmproot) { +			while (newroot && newroot != tmproot) {  				tmproot = newroot;  				newroot = collapse_null_terms(tmproot);  			} @@ -49,14 +50,16 @@ shared_ptr<CSGTerm> CSGTermNormalizer::normalizePass(shared_ptr<CSGTerm> term)  		while (term && match_and_replace(term)) {	}  		this->nodecount++;  		if (nodecount > this->limit) { +			PRINTB("WARNING: Normalized tree is growing past %d elements. Aborting normalization.\n", this->limit); +			this->aborted = true;  			return shared_ptr<CSGTerm>();  		}  		if (!term || term->type == CSGTerm::TYPE_PRIMITIVE) return term;  		if (term->left) term->left = normalizePass(term->left); -	} while (term->type != CSGTerm::TYPE_UNION && +	} while (!this->aborted && term->type != CSGTerm::TYPE_UNION &&  					 ((term->right && term->right->type != CSGTerm::TYPE_PRIMITIVE) ||  						(term->left && term->left->type == CSGTerm::TYPE_UNION))); -	term->right = normalizePass(term->right); +	if (!this->aborted) term->right = normalizePass(term->right);  	// FIXME: Do we need to take into account any transformation of item here?  	return collapse_null_terms(term); diff --git a/src/csgtermnormalizer.h b/src/csgtermnormalizer.h index c331f11..f7a444f 100644 --- a/src/csgtermnormalizer.h +++ b/src/csgtermnormalizer.h @@ -17,6 +17,7 @@ private:  	shared_ptr<CSGTerm> collapse_null_terms(const shared_ptr<CSGTerm> &term);  	unsigned int count(const shared_ptr<CSGTerm> &term) const; +	bool aborted;  	size_t limit;  	size_t nodecount;  	shared_ptr<class CSGTerm> rootnode; diff --git a/src/import.cc b/src/import.cc index 6a6d925..8980448 100644 --- a/src/import.cc +++ b/src/import.cc @@ -52,6 +52,9 @@ namespace fs = boost::filesystem;  using namespace boost::assign; // bring 'operator+=()' into scope  #include "boosty.h" +#include <boost/detail/endian.hpp> +#include <boost/cstdint.hpp> +  class ImportModule : public AbstractModule  {  public: @@ -112,6 +115,47 @@ AbstractNode *ImportModule::evaluate(const Context *ctx, const ModuleInstantiati  	return node;  } +#define STL_FACET_NUMBYTES 4*3*4+2 +// as there is no 'float32_t' standard, we assume the systems 'float' +// is a 'binary32' aka 'single' standard IEEE 32-bit floating point type +union stl_facet { +	uint8_t data8[ STL_FACET_NUMBYTES ]; +	uint32_t data32[4*3]; +	struct facet_data { +	  float i, j, k; +	  float x1, y1, z1; +	  float x2, y2, z2; +	  float x3, y3, z3; +	  uint16_t attribute_byte_count; +	} data; +}; + +void uint32_byte_swap( uint32_t &x ) +{ +#if defined(__GNUC__) || defined(__clang__) +	x = __builtin_bswap32( x ); +#elif defined(_MSC_VER) +	x = _byteswap_ulong( x ); +#else +	uint32_t b1 = ( 0x000000FF & x ) << 24; +	uint32_t b2 = ( 0x0000FF00 & x ) << 8; +	uint32_t b3 = ( 0x00FF0000 & x ) >> 8; +	uint32_t b4 = ( 0xFF000000 & x ) >> 24; +	x = b1 | b2 | b3 | b4; +#endif +} + +void read_stl_facet( std::ifstream &f, stl_facet &facet ) +{ +	f.read( (char*)facet.data8, STL_FACET_NUMBYTES ); +#ifdef BOOST_BIG_ENDIAN +	for ( int i = 0; i < 12; i++ ) { +		uint32_byte_swap( facet.data32[ i ] ); +	} +	// we ignore attribute byte count +#endif +} +  PolySet *ImportNode::evaluate_polyset(class PolySetEvaluator *) const  {  	PolySet *p = NULL; @@ -137,9 +181,11 @@ PolySet *ImportNode::evaluate_polyset(class PolySetEvaluator *) const  		int file_size = f.tellg();  		f.seekg(80);  		if (!f.eof()) { -			int facenum = 0; -			// FIXME: Assumes little endian -			f.read((char *)&facenum, sizeof(int)); +			uint32_t facenum = 0; +			f.read((char *)&facenum, sizeof(uint32_t)); +#ifdef BOOST_BIG_ENDIAN +			uint32_byte_swap( facenum ); +#endif  			if (file_size == 80 + 4 + 50*facenum) binary = true;  		}  		f.seekg(0); @@ -186,32 +232,14 @@ PolySet *ImportNode::evaluate_polyset(class PolySetEvaluator *) const  		else  		{  			f.ignore(80-5+4); -			// FIXME: Assumes little endian  			while (1) { -#ifdef _MSC_VER -#pragma pack(push,1) -#endif -				struct { -					float i, j, k; -					float x1, y1, z1; -					float x2, y2, z2; -					float x3, y3, z3; -					unsigned short acount; -				} -#ifdef __GNUC__ -				__attribute__ ((packed)) -#endif -				stldata; -#ifdef _MSC_VER -#pragma pack(pop) -#endif - -				f.read((char*)&stldata, sizeof(stldata)); +				stl_facet facet; +				read_stl_facet( f, facet );  				if (f.eof()) break;  				p->append_poly(); -				p->append_vertex(stldata.x1, stldata.y1, stldata.z1); -				p->append_vertex(stldata.x2, stldata.y2, stldata.z2); -				p->append_vertex(stldata.x3, stldata.y3, stldata.z3); +				p->append_vertex(facet.data.x1, facet.data.y1, facet.data.z1); +				p->append_vertex(facet.data.x2, facet.data.y2, facet.data.z2); +				p->append_vertex(facet.data.x3, facet.data.y3, facet.data.z3);  			}  		}  	} diff --git a/testdata/scad/bugs/issue267-normalization-crash.scad b/testdata/scad/bugs/issue267-normalization-crash.scad new file mode 100644 index 0000000..e4e3d87 --- /dev/null +++ b/testdata/scad/bugs/issue267-normalization-crash.scad @@ -0,0 +1,86 @@ +/* + *  Reported by Justin Charette + *  Causes a crash in CSGTermNormalizer::normalize() when CSG element count + *  exceeds limit setting in preferences (verified with default value of 2000). + */ + + +$fn=20; + +/* donut (r1, r2, t) {{{ +  r1 = radius of torus +  r2 = radius of torus cross section (circle) +  t  = thickness of shell (t == 0 is  +*/ +module donut (r1, r2, t=0) { +  difference() { +    rotate_extrude( convexity=6 ) { +      translate([r1, 0, 0]) { +        circle( r = r2 ); +      } +    } +    // (t == 0 ? solid : hollow )  +    if (t > 0) { +      rotate_extrude( convexity=6 ) { +        translate([r1, 0, 0]) { +          circle( r = r2-t ); +        } +      } +    } +  } +} //}}} + +/* half donut (r1, r2, t, round) {{{ +  r1     = radius of torus +  r2     = radius of torus cross section (circle) +  t      = thickness of shell +  round  = trim ends of semi-torus so they are round +*/ +module half_donut (r1, r2, t=1, round=false) { +  difference() { +    donut( r1, r2, t ); +    difference() { +      translate( [0, -((r1+r2)/2+0.5), 0] ) +        scale( [2*(r1+r2)+1, r1+r2+1, 2*r2+1] ) +          square( 1, center=true ); +      if (round) { +        rotate( 90, [0, 1, 0] ) +          cylinder( 2*(r1+r2)+2, r2, r2, center=true ); +      } +    } +  } +} //}}} + +/* donut flange (r1, r2, a1, a2, a_step, t, round) {{{ +  r1      = radius of torus +  r2      = radius of torus cross section (circle) +  a1      = starting angle of flange rotation +  a2      = stopping angle of flange rotation +  a_step  = increment size of flange rotation +  t       = thickness of shell (t == 0 is solid, t in (0, r2) is hollow) +  round   = (true/false) to trim ends of semi-torus so they are round +*/ +module donut_flange (r1, r2, a1, a2, a_step=1, t=0, round=false) { +  difference() { +    union() { +      for (a = [a1:a_step:a2]) { +        rotate( a, [1, 0, 0] ) +          half_donut( r1, r2, round ); +      } +    } +    // (t == 0 ? solid : hollow )  +    if (t > 0) { +      union() { +        for (a = [a1:a_step:a2]) { +          rotate( a, [1, 0, 0] ) +            half_donut( r1, r2-t, round ); +        } +      } +    } +  } +} //}}} + +donut( 20, 5 ); +donut_flange( 20, 5, 0, 50, 10, t=1, round=false ); + +// vim: set et sw=2 ts=2 sts=2 ai sta sr fdm=marker: diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bb2ab06..bcdd6af 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -179,6 +179,11 @@ endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")  set(CMAKE_INCLUDE_DIRECTORIES_BEFORE ON)  find_package(OpenGL REQUIRED) +if ( "${OPENGL_glu_LIBRARY}" MATCHES "NOTFOUND" ) +  # GLU and Mesa split in late 2012 so some systems dont have GLU +  find_library(OPENGL_glu_LIBRARY GLU HINTS "$ENV{OPENSCAD_LIBRARIES}/lib" REQUIRED) +  set( OPENGL_LIBRARY ${OPENGL_glu_LIBRARY} ${OPENGL_LIBRARY} ) +endif()  if (MINGW_CROSS_ENV_DIR)     mingw_cross_env_find_qt() @@ -822,6 +827,15 @@ endif()  # 1. Start/stop Virtual Framebuffer for linux/bsd. 2. Pretty Print  # Please see the CTestCustom.template file for more info.  +# +# Post-test pretty print +# + +add_executable(test_pretty_print test_pretty_print.cc) +set_target_properties(test_pretty_print PROPERTIES COMPILE_FLAGS +  "-DPYBIN=${PYTHON_EXECUTABLE} -DPYSRC=test_pretty_print.py -DBUILDDIR=--builddir=${CMAKE_CURRENT_BINARY_DIR}" +) +  file(READ ${CMAKE_CURRENT_SOURCE_DIR}/CTestCustom.template TMP)  string(REPLACE __cmake_current_binary_dir__ ${CMAKE_CURRENT_BINARY_DIR} TMP ${TMP})  string(REPLACE __cmake_current_source_dir__ ${CMAKE_CURRENT_SOURCE_DIR} TMP ${TMP}) diff --git a/tests/CTestCustom.template b/tests/CTestCustom.template index 72e6443..338f4b6 100644 --- a/tests/CTestCustom.template +++ b/tests/CTestCustom.template @@ -24,8 +24,7 @@ if( __cmake_system_name__ MATCHES "Linux|BSD")   else()    message("X11 DISPLAY environment variable not found. Calling virtualfb.sh")    execute_process( -   COMMAND __cmake_current_source_dir__/virtualfb.sh start -   OUTPUT_VARIABLE SVFB_OUT) +   COMMAND __cmake_current_source_dir__/virtualfb.sh OUTPUT_VARIABLE SVFB_OUT)    string(REGEX MATCH "DISPLAY=:[0-9.]*" VFB_DISPLAY_STR "${SVFB_OUT}")    string(REGEX MATCH ":[0-9.]*" VFB_DISPLAY "${VFB_DISPLAY_STR}")    string(REGEX MATCH "PID=[0-9.]*" VFB_PID_STR "${SVFB_OUT}") @@ -37,8 +36,10 @@ if( __cmake_system_name__ MATCHES "Linux|BSD")      message("Process ID of vfb: ${VFB_PID}")    endif()    if ("${VFB_DISPLAY}" STREQUAL "" OR "${VFB_PID}" STREQUAL "") -    message("Virtual framebuffer had a problem starting.") -    execute_process("cat virtualfblog") +    set(VFBLOG "virtualfb.log") +    message("Virtual framebuffer had a problem starting. Printing ${VFBLOG}") +    execute_process(COMMAND cat virtualfb.log OUTPUT_VARIABLE VFBLOGTXT) +    message("Log: ${VFBLOGTXT}")    else()      message("Virtual framebuffer started. DISPLAY=${VFB_DISPLAY}, PID=${VFB_PID}")    endif() @@ -50,7 +51,7 @@ if( __cmake_system_name__ MATCHES "Linux|BSD")    # in the build directory).    set(ENV{DISPLAY} "${VFB_DISPLAY}") -  set(CTEST_CUSTOM_POST_TEST "kill ${VFB_PID}") +  set(CTEST_CUSTOM_POST_TEST "__cmake_current_source_dir__/virtualfb.sh")   endif()  endif() @@ -59,7 +60,7 @@ endif()  message("running 'opencsgtest --info' to generate sysinfo.txt")  execute_process(COMMAND __wine__ __cmake_current_binary_dir__/opencsgtest --info OUTPUT_FILE sysinfo.txt) -set(CTEST_CUSTOM_POST_TEST ${CTEST_CUSTOM_POST_TEST} "__python__ __cmake_current_source_dir__/test_pretty_print.py --builddir=__cmake_current_binary_dir__") +set(CTEST_CUSTOM_POST_TEST ${CTEST_CUSTOM_POST_TEST} "__cmake_current_binary_dir__/test_pretty_print")  if ( ${debug_openscad_template} )    foreach(post_test ${CTEST_CUSTOM_POST_TEST} ) diff --git a/tests/test_cmdline_tool.py b/tests/test_cmdline_tool.py index 78524bf..ebe60df 100755 --- a/tests/test_cmdline_tool.py +++ b/tests/test_cmdline_tool.py @@ -107,7 +107,7 @@ def compare_png(resultfilename):      msg += '\n expected image: ' + expectedfilename + '\n'      print >> sys.stderr, msg      if not resultfilename: -        print >> sys.stderr, "Error: OpenSCAD did not generate an image to test" +        print >> sys.stderr, "Error: OpenSCAD error during test image generation"          return False      print >> sys.stderr, ' actual image: ', resultfilename diff --git a/tests/test_pretty_print.cc b/tests/test_pretty_print.cc new file mode 100644 index 0000000..9959189 --- /dev/null +++ b/tests/test_pretty_print.cc @@ -0,0 +1,24 @@ +/* Workaround for CTEST_CUSTOM_POST_TEST not allowing arguments + compile with + -DPYBIN=/usr/bin/python + -DPYSRC=/home/janedoe/openscad/tests/test_pretty_print.py + -DBUILDDIR=--builddir=/home/janedoe/openscad/tests/bin" +*/ + +#include <unistd.h> +//#include <stdio.h> + +#define PREQUOTE(x) #x +#define QUOTE(x) PREQUOTE(x) +int main( int argc, char * argv[] ) +{ +	char *newargs[4]; +	newargs[0] = const_cast<char *>(QUOTE( PYBIN )); +	newargs[1] = const_cast<char *>(QUOTE( PYSRC )); +	newargs[2] = const_cast<char *>(QUOTE( BUILDDIR )); +	newargs[3] = NULL; +	//printf(":%s:%s:%s\n", newargs[0], newargs[1], newargs[2]); +	return execv( newargs[0], newargs ); +} + + diff --git a/tests/virtualfb.sh b/tests/virtualfb.sh index 3c0cf0e..5abd804 100755 --- a/tests/virtualfb.sh +++ b/tests/virtualfb.sh @@ -1,22 +1,64 @@  #!/bin/sh -if [ "`command -v Xvfb`" ]; then -  VFB_BINARY=Xvfb -fi +# Toggle the Virtual Framebuffer +# If started, stop. If stopped, start. -if [ "`command -v Xvnc`" ]; then -  VFB_BINARY=Xvnc -fi +start() +{ +  if [ "`command -v Xvfb`" ]; then +    VFB_BINARY=Xvfb +  fi + +  if [ "`command -v Xvnc`" ]; then +    VFB_BINARY=Xvnc +  fi + +  if [ ! $VFB_BINARY ]; then +    echo "$0 Failed, cannot find Xvfb or Xvnc" +    exit 1 +  fi + +  VFB_DISPLAY=`echo | awk 'BEGIN{srand();} {printf ":%.0f", rand()*1000+100};'` +  $VFB_BINARY $VFB_DISPLAY -screen 0 800x600x24 &> ./virtualfb.log & +  VFB_PID=$! + +  echo $VFB_DISPLAY > ./virtualfb.DISPLAY +  echo $VFB_PID > ./virtualfb.PID + +  echo "Started virtual fb, PID=$VFB_PID , DISPLAY=$VFB_DISPLAY" +  sleep 1 +} + +stop() +{ +  VFB_PID=`cat ./virtualfb.PID` +  VFB_DISPLAY=`cat ./virtualfb.DISPLAY` + +  echo "Stopping virtual fb, PID was $VFB_PID, DISPLAY was $VFB_DISPLAY" +  kill $VFB_PID +  LOCKFILE=`echo "/tmp/.X"$VFB_DISPLAY"-lock"` +  if [ -e $LOCKFILE ]; then +    rm $LOCKFILE +  fi +  rm ./virtualfb.PID +  rm ./virtualfb.DISPLAY +} + +isrunning() +{ +  isrunning_result= +  if [ -e ./virtualfb.PID ]; then +    VFB_PID=`cat ./virtualfb.PID` +    if [ "`ps cax | awk ' { print $1 } ' | grep ^$VFB_PID\$`" ]; then +      isrunning_result=1 +    fi +  fi +} -if [ ! $VFB_BINARY ]; then -  echo "$0 Failed, cannot find Xvfb or Xvnc" -  exit 1 +isrunning +if [ $isrunning_result ]; then +  stop +else +  start  fi -DISPLAY=:98 -$VFB_BINARY $DISPLAY -screen 0 800x600x24 &> virtualfblog & -echo PID=$! " " -echo DISPLAY=$DISPLAY -# trap "kill -KILL $xpid ||:" EXIT -export DISPLAY -sleep 3 | 
