Index: cpp/common/framsg.cpp
===================================================================
--- cpp/common/framsg.cpp	(revision 167)
+++ cpp/common/framsg.cpp	(revision 180)
@@ -5,4 +5,5 @@
 #include "framsg.h"
 #include <common/nonstd_stdio.h>
+#include "stl-util.h"
 #include "Convert.h"
 
@@ -11,7 +12,6 @@
 void FMprintf_va(const char *o,const char *m,int w,const char *bl,va_list va)
 {
-	char buf[10000];
-	vsnprintf(buf,10000,bl,va);
-	FramMessage(o,m,buf,w);
+	string buf=ssprintf_va(bl,va);
+	FramMessage(o,m,buf.c_str(),w);
 }
 
Index: cpp/common/stl-util.cpp
===================================================================
--- cpp/common/stl-util.cpp	(revision 180)
+++ cpp/common/stl-util.cpp	(revision 180)
@@ -0,0 +1,101 @@
+#include "stl-util.h"
+#include <stdarg.h>
+#include <stdlib.h>
+#include "nonstd_stdio.h"
+#include "nonstd.h"
+#include "framsg.h"
+
+string ssprintf_va(const char* format, va_list ap)
+{
+	string s; //clang crashed when this declaration was in s=buf - dreadful GOTO? - i doubt it... goto did not skip over any variable declarations in this case
+	long size=1000;
+	char* buf;
+retry:
+	buf=(char*)malloc(size);
+	if (vsnprintf(buf,size,format,ap)>=size) {free(buf); size*=4; goto retry;}
+	s=buf;
+	free(buf);
+	return s;
+}
+
+string ssprintf(const char* format, ...)
+{
+	va_list ap;
+	va_start(ap, format);
+	string ret=ssprintf_va(format,ap); //is it too wasteful? copying the string again... unless the compiler can handle it better
+	va_end(ap);
+	return ret;
+}
+
+bool readCompleteFile(const char* filename, vector<char>& data, bool warn_on_missing_file)
+{
+	MFILE *f=mfopen(filename,FOPEN_READ_BINARY);
+	bool ok=f!=NULL;
+	if (f)
+	{
+		mfseek(f,0,SEEK_END);
+		long size=mftell(f);
+		mfseek(f,0,SEEK_SET);
+		data.resize(size);
+		int przeczytane=mfread(&data[0],size,1,f);
+		mfclose(f);
+		ok&=przeczytane==1;
+	}
+	if (warn_on_missing_file && !ok)
+		FMprintf("stl-util","readCompleteFile",FMLV_WARN,"Couldn't open file '%s'",filename);
+	return ok;
+}
+
+bool readCompleteFile(const char* filename, string& out, bool warn_on_missing_file)
+{
+	std::vector<char> data;
+	if (readCompleteFile(filename,data,warn_on_missing_file))
+	{
+		out=string(&data[0],data.size());
+		return true;
+	}
+	return false;
+}
+
+bool writeCompleteFile(const char* filename, const string& text, bool warn_on_fail)
+{
+	MFILE *f=mfopen(filename,FOPEN_WRITE_BINARY);
+	bool ok=f!=NULL;
+	if (f)
+	{
+		int zapisane=mfwrite(text.c_str(),text.length(),1,f);
+		mfclose(f);
+		ok&=zapisane==1;
+	}
+	if (warn_on_fail && !ok)
+		FMprintf("stl-util","writeCompleteFile",FMLV_WARN,"couldn't write file '%s'",filename);
+	return ok;
+}
+
+bool writeCompleteFile(const char* filename, vector<char>& data, bool warn_on_fail)
+{
+	string s(&data[0],data.size());
+	return writeCompleteFile(filename, s, warn_on_fail);
+}
+
+
+
+std::string stripExt(const std::string& filename)
+{
+	int dot=filename.rfind('.');
+	if (dot==std::string::npos) return filename;
+	int sep=filename.rfind(PATH_SEPARATOR_CHAR);
+	if ((sep==std::string::npos)||(sep<dot))
+		return filename.substr(0,dot);
+	return filename;
+}
+
+std::string getFileExt(const std::string& filename)
+{
+	int dot=filename.rfind('.');
+	if (dot==std::string::npos) return string("");
+	int sep=filename.rfind(PATH_SEPARATOR_CHAR);
+	if ((sep==std::string::npos)||(sep<dot))
+		return filename.substr(dot);
+	return string("");
+}
Index: cpp/common/stl-util.h
===================================================================
--- cpp/common/stl-util.h	(revision 167)
+++ cpp/common/stl-util.h	(revision 180)
@@ -7,4 +7,5 @@
 
 #include "nonstd_stl.h"
+#include <stdarg.h>
 
 template<typename T, std::size_t N> void push_back(vector<T>& v, T(&d)[N])
@@ -37,6 +38,8 @@
 
 string ssprintf(const char* format, ...);
+string ssprintf_va(const char* format, va_list ap);
 
 string stripExt(const string& filename); // strip extension from filename
+string getFileExt(const string& filename); // get extension (starting with ".") from filename
 
 bool readCompleteFile(const char* filename, vector<char>& data, bool warn_on_missing_file=true);
