From e386edfdb945c89cdb8ba2faccc4e68018678a17 Mon Sep 17 00:00:00 2001 From: Royce Mitchell III Date: Wed, 22 Dec 2004 21:53:02 +0000 Subject: [PATCH] commited the wrong source for the bot.. sorry svn path=/trunk/; revision=12291 --- rosapps/games/ArchBlackmann/ArchBlackmann.cpp | 57 +- rosapps/games/ArchBlackmann/ArchBlackmann.dsp | 16 + rosapps/games/ArchBlackmann/File.cpp | 265 +++++ rosapps/games/ArchBlackmann/File.h | 173 +++ rosapps/games/ArchBlackmann/ssprintf.cpp | 998 ++++++++++++++++++ rosapps/games/ArchBlackmann/ssprintf.h | 12 + 6 files changed, 1504 insertions(+), 17 deletions(-) create mode 100644 rosapps/games/ArchBlackmann/File.cpp create mode 100644 rosapps/games/ArchBlackmann/File.h create mode 100644 rosapps/games/ArchBlackmann/ssprintf.cpp create mode 100644 rosapps/games/ArchBlackmann/ssprintf.h diff --git a/rosapps/games/ArchBlackmann/ArchBlackmann.cpp b/rosapps/games/ArchBlackmann/ArchBlackmann.cpp index 905af5ebbd8..069f4535cec 100644 --- a/rosapps/games/ArchBlackmann/ArchBlackmann.cpp +++ b/rosapps/games/ArchBlackmann/ArchBlackmann.cpp @@ -4,18 +4,35 @@ #pragma warning ( disable : 4786 ) #endif//_MSC_VER -#include +#include #include +#include "File.h" +#include "ssprintf.h" + #include "IRCClient.h" using std::string; using std::vector; +const char* ArchBlackmann = "ArchBlackmann"; + +vector tech_replies; + +const char* TechReply() +{ + return tech_replies[rand()%tech_replies.size()].c_str(); +} + // do custom stuff with the IRCClient from your subclass via the provided callbacks... class MyIRCClient : public IRCClient { + File flog; public: + MyIRCClient() + { + flog.open ( "arch.log", "w+" ); + } // see IRCClient.h for documentation on these callbacks... bool OnConnected() { @@ -32,13 +49,21 @@ public: bool OnPrivMsg ( const string& from, const string& text ) { printf ( "<%s> %s\n", from.c_str(), text.c_str() ); - return true; + flog.printf ( "<%s> %s\n", from.c_str(), text.c_str() ); + return PrivMsg ( from, "hey, your tongue doesn't belong there!" ); } bool OnChannelMsg ( const string& channel, const string& from, const string& text ) { printf ( "%s <%s> %s\n", channel.c_str(), from.c_str(), text.c_str() ); - if ( !stricmp ( from.c_str(), "royce3" ) ) - PrivMsg ( channel, text ); + flog.printf ( "%s <%s> %s\n", channel.c_str(), from.c_str(), text.c_str() ); + string text2(text); + strlwr ( &text2[0] ); + if ( !strnicmp ( text2.c_str(), ArchBlackmann, strlen(ArchBlackmann) ) ) + { + string reply = ssprintf("%s: %s", from.c_str(), TechReply()); + flog.printf ( "TECH-REPLY: %s\n", reply.c_str() ); + return PrivMsg ( channel, reply ); + } return true; } bool OnChannelMode ( const string& channel, const string& mode ) @@ -72,6 +97,13 @@ public: int main ( int argc, char** argv ) { + srand ( time(NULL) ); + File f ( "tech.txt", "r" ); + string line; + while ( f.next_line ( line, true ) ) + tech_replies.push_back ( line ); + f.close(); + printf ( "initializing IRCClient debugging\n" ); IRCClient::SetDebug ( true ); printf ( "calling suStartup()\n" ); @@ -79,19 +111,19 @@ int main ( int argc, char** argv ) printf ( "creating IRCClient object\n" ); MyIRCClient irc; printf ( "connecting to freenode\n" ); - if ( !irc.Connect ( "140.211.166.3" ) ) // irc.freenode.net + if ( !irc.Connect ( "212.204.214.114" ) ) // irc.freenode.net { printf ( "couldn't connect to server\n" ); return -1; } printf ( "sending user command\n" ); - if ( !irc.User ( "Royce3", "", "irc.freenode.net", "Royce Mitchell III" ) ) + if ( !irc.User ( "ArchBlackmann", "", "irc.freenode.net", "Arch Blackmann" ) ) { printf ( "USER command failed\n" ); return -1; } printf ( "sending nick\n" ); - if ( !irc.Nick ( "Royce3" ) ) + if ( !irc.Nick ( "ArchBlackmann" ) ) { printf ( "NICK command failed\n" ); return -1; @@ -109,15 +141,6 @@ int main ( int argc, char** argv ) return -1; } printf ( "entering irc client processor\n" ); - irc.Run ( true ); // do the processing in this thread... - string cmd; - for ( ;; ) - { - char c = getch(); - if ( c == '\n' || c == '\r' ) - { - - } - } + irc.Run ( false ); // do the processing in this thread... return 0; } diff --git a/rosapps/games/ArchBlackmann/ArchBlackmann.dsp b/rosapps/games/ArchBlackmann/ArchBlackmann.dsp index 9b959184d44..951c33fc898 100644 --- a/rosapps/games/ArchBlackmann/ArchBlackmann.dsp +++ b/rosapps/games/ArchBlackmann/ArchBlackmann.dsp @@ -118,6 +118,14 @@ SOURCE=.\cram_md5.h # End Source File # Begin Source File +SOURCE=.\File.cpp +# End Source File +# Begin Source File + +SOURCE=.\File.h +# End Source File +# Begin Source File + SOURCE=.\IRCClient.cpp # End Source File # Begin Source File @@ -174,6 +182,14 @@ SOURCE=.\SplitJoin.h # End Source File # Begin Source File +SOURCE=.\ssprintf.cpp +# End Source File +# Begin Source File + +SOURCE=.\ssprintf.h +# End Source File +# Begin Source File + SOURCE=.\ThreadPool.cpp # End Source File # Begin Source File diff --git a/rosapps/games/ArchBlackmann/File.cpp b/rosapps/games/ArchBlackmann/File.cpp new file mode 100644 index 00000000000..d6faf5d57f9 --- /dev/null +++ b/rosapps/games/ArchBlackmann/File.cpp @@ -0,0 +1,265 @@ +// File.cpp +// (C) 2002-2004 Royce Mitchell III +// Dually licensed under BSD & LGPL + +#ifdef _MSC_VER +#pragma warning ( disable : 4786 ) +#endif//_MSC_VER + +#include +#include +#include "File.h" + +#ifndef nelem +#define nelem(x) ( sizeof(x) / sizeof(x[0]) ) +#endif//nelem + +using File::filesize_t; +using File::fileoff_t; + + +fileoff_t File::seek ( fileoff_t offset ) +{ +#ifdef WIN32 + if ( _f->_flag & _IOWRT ) // is there pending output? + fflush ( _f ); + + // reset "buffered input" variables + _f->_cnt = 0; + _f->_ptr = _f->_base; + + // make sure we're going forward + if ( _f->_flag & _IORW ) + _f->_flag &= ~(_IOREAD|_IOWRT); + + return _lseeki64 ( _fileno(_f), offset, SEEK_SET ); +#else//UNIX + return lseek64 ( fileno(_f), offset, SEEK_SET ); +#endif +} + +std::string File::getline ( bool strip_crlf /*= false*/ ) +{ + std::string s = ""; + char buf[256]; + for ( ;; ) + { + *buf = 0; + fgets ( buf, nelem(buf)-1, _f ); + if ( !*buf ) + break; + s += buf; + if ( strchr ( "\r\n", buf[strlen(buf)-1] ) ) + break; + } + if ( strip_crlf && s.size() ) + { + char* p = strpbrk ( &s[0], "\r\n" ); + if ( p ) + { + *p = '\0'; + s.resize ( p-&s[0] ); + } + } + return s; +} + +std::wstring File::wgetline ( bool strip_crlf /*= false*/ ) +{ + std::wstring s = L""; + wchar_t buf[256]; + for ( ;; ) + { + *buf = 0; + fgetws ( buf, nelem(buf)-1, _f ); + if ( !*buf ) + break; + s += buf; + if ( wcschr ( L"\r\n", buf[wcslen(buf)-1] ) ) + break; + } + if ( strip_crlf && s.size() ) + { + wchar_t* p = wcspbrk ( &s[0], L"\r\n" ); + if ( p ) + { + *p = L'\0'; + s.resize ( (p-&s[0])/sizeof(wchar_t) ); + } + } + return s; +} + +// this function searches for the next end-of-line and puts all data it +// finds until then in the 'line' parameter. +// +// call continuously until the function returns false ( no more data ) +bool File::next_line ( std::string& line, bool strip_crlf ) +{ + line = getline(strip_crlf); + // indicate that we're done *if*: + // 1) there's no more data, *and* + // 2) we're at the end of the file + return line.size()>0 || !eof(); +} + +bool File::next_line ( std::wstring& line, bool strip_crlf ) +{ + line = wgetline ( strip_crlf ); + return line.size()>0 || !eof(); +} + +/* +example usage: + +bool mycallback ( const std::string& line, int line_number, long lparam ) +{ + std::cout << line << std::endl; + return true; // continue enumeration +} + +File f ( "file.txt", "rb" ); // open file for binary read-only ( i.e. "rb" ) +f.enum_lines ( mycallback, 0, true ); +*/ + +/*bool File::enum_lines ( bool (*callback)(const std::string& line, int line_number, long lparam), long lparam, bool strip_crlf ) +{ + int line_number = 0; + for ( ;; ) + { + std::string s = getline(strip_crlf); + line_number++; + if ( !s.size() ) + { + if ( eof() ) + return true; + else + continue; + } + if ( !(*callback) ( s, line_number, lparam ) ) + return false; + } +}*/ + +filesize_t File::length() const +{ +#ifdef WIN32 + return _filelengthi64 ( _fileno(_f) ); +#elif defined(UNIX) + struct stat64 file_stat; + verify(fstat64(fileno(_f), &file_stat) == 0); + return file_stat.st_size; +#endif +} + +void File::close() +{ + if ( _f ) + { + fclose(_f); + _f = 0; + } +} + +void File::printf ( const char* fmt, ... ) +{ + va_list arg; + int done; + + va_start(arg, fmt); + assert(_f); + done = vfprintf ( _f, fmt, arg ); + va_end(arg); +} + +/*static*/ bool File::LoadIntoString ( std::string& s, const std::string& filename ) +{ + File in ( filename, "rb" ); + if ( !in.isopened() ) + return false; + filesize_t flen = in.length(); + size_t len = size_t(flen); + if ( len != flen ) + return false; // file too big... + s.resize ( len + 1 ); + if ( !in.read ( &s[0], len ) ) + return false; + s[len] = '\0'; + s.resize ( len ); + return true; +} + +/*static*/ bool File::LoadIntoString ( std::string& s, const std::wstring& filename ) +{ + File in ( filename, L"rb" ); + if ( !in.isopened() ) + return false; + filesize_t flen = in.length(); + size_t len = size_t(flen); + if ( len != flen ) + return false; // file too big... + s.resize ( len + 1 ); + if ( !in.read ( &s[0], len ) ) + return false; + s[len] = '\0'; + s.resize ( len ); + return true; +} + +/*static*/ bool File::SaveFromString ( const std::string& filename, const std::string& s, bool binary ) +{ + File out ( filename, binary ? "wb" : "w" ); + if ( !out.isopened() ) + return false; + out.write ( s.c_str(), s.size() ); + return true; +} + +/*static*/ bool File::SaveFromString ( const std::wstring& filename, const std::string& s, bool binary ) +{ + File out ( filename, binary ? L"wb" : L"w" ); + if ( !out.isopened() ) + return false; + out.write ( s.c_str(), s.size() ); + return true; +} + +/*static*/ bool File::SaveFromBuffer ( const std::string& filename, const char* buf, size_t buflen, bool binary ) +{ + File out ( filename, binary ? "wb" : "w" ); + if ( !out.isopened() ) + return false; + out.write ( buf, buflen ); + return true; +} + +/*static*/ bool File::SaveFromBuffer ( const std::wstring& filename, const char* buf, size_t buflen, bool binary ) +{ + File out ( filename, binary ? L"wb" : L"w" ); + if ( !out.isopened() ) + return false; + out.write ( buf, buflen ); + return true; +} + +/*static*/ std::string File::TempFileName ( const std::string& prefix ) +{ +#ifdef WIN32 + std::string s ( _tempnam ( ".", prefix.c_str() ) ); + return s; +#else + // FIXME + return string(""); +#endif +} + +/*static*/ std::wstring File::TempFileName ( const std::wstring& prefix ) +{ +#ifdef WIN32 + std::wstring s ( _wtempnam ( L".", prefix.c_str() ) ); + return s; +#else + // FIXME + return std::wstring(L""); +#endif +} diff --git a/rosapps/games/ArchBlackmann/File.h b/rosapps/games/ArchBlackmann/File.h new file mode 100644 index 00000000000..a3ab5c1c141 --- /dev/null +++ b/rosapps/games/ArchBlackmann/File.h @@ -0,0 +1,173 @@ +// File.h +// (C) 2002-2004 Royce Mitchell III +// Dually licensed under BSD & LGPL + +#ifndef FILE_H +#define FILE_H + +#ifdef WIN32 +# include // fgetc +# include +#elif defined(UNIX) +# include +# include +#endif +#include +#include + +class File +{ +public: +#ifdef _MSC_VER + typedef __int64 fileoff_t; + typedef unsigned __int64 filesize_t; +#else//_MSC_VER + typedef __off64_t fileoff_t; + typedef __size64_t filesize_t; +#endif//_MSC_VER + + File() : _f(0) + { + } + + File ( const std::string& filename, const char* mode ) : _f(0) + { + open ( filename, mode ); + } + + File ( const std::wstring& filename, const wchar_t* mode ) : _f(0) + { + open ( filename, mode ); + } + + File ( const char* filename, const char* mode ) : _f(0) + { + open ( filename, mode ); + } + + File ( const wchar_t* filename, const wchar_t* mode ) : _f(0) + { + open ( filename, mode ); + } + + ~File() + { + close(); + } + + bool open ( const std::string& filename, const char* mode ) + { + assert ( !_f ); + return ( _f = fopen ( filename.c_str(), mode ) ) != 0; + } + + bool open ( const std::wstring& filename, const wchar_t* mode ) + { + assert ( !_f ); + return ( _f = _wfopen ( filename.c_str(), mode ) ) != 0; + } + + bool open ( const char* filename, const char* mode ) + { + assert ( !_f ); + return ( _f = fopen ( filename, mode ) ) != 0; + } + + bool open ( const wchar_t* filename, const wchar_t* mode ) + { + assert ( !_f ); + return ( _f = _wfopen ( filename, mode ) ) != 0; + } + + fileoff_t seek ( fileoff_t offset ); + + int get() + { + return fgetc ( _f ); + } + + bool put ( int c ) + { + return fputc ( c, _f ) != EOF; + } + + std::string getline ( bool strip_crlf = false ); + std::wstring wgetline ( bool strip_crlf = false ); + + // this function searches for the next end-of-line and puts all data it + // finds until then in the 'line' parameter. + // + // call continuously until the function returns false ( no more data ) + bool next_line ( std::string& line, bool strip_crlf ); + bool next_line ( std::wstring& line, bool strip_crlf ); + + bool read ( void* data, unsigned len ) + { + return len == fread ( data, 1, len, _f ); + } + + bool write ( const void* data, unsigned len ) + { + return len == fwrite ( data, 1, len, _f ); + } + + bool write ( const std::string& data ) + { + return data.length() == fwrite ( data.c_str(), 1, data.length(), _f ); + } + + bool write ( const std::wstring& data ) + { + return data.length() == fwrite ( data.c_str(), sizeof(data[0]), data.length(), _f ); + } + + filesize_t length() const; + + void close(); + + bool isopened() const + { + return _f != 0; + } + + bool is_open() const + { + return _f != 0; + } + + bool eof() const + { + return feof(_f) ? true : false; + } + + FILE* operator * () + { + return _f; + } + + operator FILE*() + { + return _f; + } + + void printf ( const char* fmt, ... ); + void printf ( const wchar_t* fmt, ... ); + + static bool LoadIntoString ( std::string& s, const std::string& filename ); + static bool LoadIntoString ( std::string& s, const std::wstring& filename ); + static bool SaveFromString ( const std::string& filename, const std::string& s, bool binary ); + static bool SaveFromString ( const std::wstring& filename, const std::string& s, bool binary ); + static bool SaveFromBuffer ( const std::string& filename, const char* buf, size_t buflen, bool binary ); + static bool SaveFromBuffer ( const std::wstring& filename, const char* buf, size_t buflen, bool binary ); + + static std::string TempFileName ( const std::string& prefix ); + static std::wstring TempFileName ( const std::wstring& prefix ); + +private: + File(const File&) {} + const File& operator = ( const File& ) { return *this; } + + FILE * _f; +}; + +#endif//FILE_H diff --git a/rosapps/games/ArchBlackmann/ssprintf.cpp b/rosapps/games/ArchBlackmann/ssprintf.cpp new file mode 100644 index 00000000000..88b829b88d1 --- /dev/null +++ b/rosapps/games/ArchBlackmann/ssprintf.cpp @@ -0,0 +1,998 @@ +// ssprintf.cpp + +#include +#include +#include +#include +#include "ssprintf.h" + +#ifdef _MSC_VER +#define alloca _alloca +#endif//_MSC_VER + +typedef __int64 LONGLONG; +typedef unsigned __int64 ULONGLONG; + +typedef struct { + unsigned int mantissa:23; + unsigned int exponent:8; + unsigned int sign:1; +} ieee_float_t; + +typedef struct { + unsigned int mantissal:32; + unsigned int mantissah:20; + unsigned int exponent:11; + unsigned int sign:1; +} ieee_double_t; + +typedef struct { + unsigned int mantissal:32; + unsigned int mantissah:32; + unsigned int exponent:15; + unsigned int sign:1; + unsigned int empty:16; +} ieee_long_double_t; + +std::string ssprintf ( const char* fmt, ... ) +{ + va_list arg; + va_start(arg, fmt); + std::string f = ssvprintf ( fmt, arg ); + va_end(arg); + return f; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ +#define ZEROTRUNC 128 /* truncate zero 's */ + + +static int skip_atoi(const char **s) +{ + int i=0; + + while (isdigit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + + +static int do_div(LONGLONG *n,int base) +{ + int __res = ((ULONGLONG) *n) % (unsigned) base; + *n = ((ULONGLONG) *n) / (unsigned) base; + return __res; +} + + +static bool number(std::string& f, LONGLONG num, int base, int size, int precision ,int type) +{ + char c,sign,tmp[66]; + const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; + int i; + + if (type & LARGE) + digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + if (type & LEFT) + type &= ~ZEROPAD; + if (base < 2 || base > 36) + return 0; + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & SIGN) { + if (num < 0) { + sign = '-'; + num = -num; + size--; + } else if (type & PLUS) { + sign = '+'; + size--; + } else if (type & SPACE) { + sign = ' '; + size--; + } + } + if (type & SPECIAL) { + if (base == 16) + size -= 2; + else if (base == 8) + size--; + } + i = 0; + if (num == 0) + tmp[i++]='0'; + else while (num != 0) + tmp[i++] = digits[do_div(&num,base)]; + if (i > precision) + precision = i; + size -= precision; + if (!(type&(ZEROPAD+LEFT))) + while(size-->0) + f += ' '; + if (sign) + f += sign; + if (type & SPECIAL) + { + if (base==8) + f += '0'; + else if (base==16) + { + f += '0'; + f += digits[33]; + } + } + if (!(type & LEFT)) + { + while (size-- > 0) + f += c; + } + while (i < precision--) + { + f += '0'; + } + while (i-- > 0) + { + f += tmp[i]; + } + while (size-- > 0) + { + f += ' '; + } + return true; +} + + +static bool numberf(std::string& f, double __n, char exp_sign, int size, int precision, int type) +{ + double exponent = 0.0; + double e; + long ie; + + //int x; + char *buf, *tmp; + int i = 0; + int j = 0; + //int k = 0; + + double frac, intr; + double p; + char sign; + char c; + char ro = 0; + int result; + + union + { + double* __n; + ieee_double_t* n; + } n; + + n.__n = &__n; + + if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) { + ie = ((unsigned int)n.n->exponent - (unsigned int)0x3ff); + exponent = ie/3.321928; + } + + if ( exp_sign == 'g' || exp_sign == 'G' ) { + type |= ZEROTRUNC; + if ( exponent < -4 || fabs(exponent) >= precision ) + exp_sign -= 2; // g -> e and G -> E + } + + if ( exp_sign == 'e' || exp_sign == 'E' ) { + frac = modf(exponent,&e); + if ( frac > 0.5 ) + e++; + else if ( frac < -0.5 ) + e--; + + result = numberf(f,__n/pow(10.0L,e),'f',size-4, precision, type); + if (result < 0) + return false; + f += exp_sign; + size--; + ie = (long)e; + type = LEFT | PLUS; + if ( ie < 0 ) + type |= SIGN; + + result = number(f,ie, 10,2, 2,type ); + if (result < 0) + return false; + return true; + } + + if ( exp_sign == 'f' ) { + buf = (char*)alloca(4096); + if (type & LEFT) { + type &= ~ZEROPAD; + } + + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & SIGN) { + if (__n < 0) { + sign = '-'; + __n = fabs(__n); + size--; + } else if (type & PLUS) { + sign = '+'; + size--; + } else if (type & SPACE) { + sign = ' '; + size--; + } + } + + frac = modf(__n,&intr); + + // # flags forces a . and prevents trucation of trailing zero's + + if ( precision > 0 ) { + //frac = modfl(__n,&intr); + i = precision-1; + while ( i >= 0 ) { + frac*=10.0L; + frac = modf(frac, &p); + buf[i] = (int)p + '0'; + i--; + } + i = precision; + size -= precision; + + ro = 0; + if ( frac > 0.5 ) { + ro = 1; + } + + if ( precision >= 1 || type & SPECIAL) { + buf[i++] = '.'; + size--; + } + } + + if ( intr == 0.0 ) { + buf[i++] = '0'; + size--; + } + else { + while ( intr > 0.0 ) { + p = intr; + intr/=10.0L; + modf(intr, &intr); + + p -= 10.0*intr; + + buf[i++] = (int)p + '0'; + size--; + } + } + + j = 0; + while ( j < i && ro == 1) { + if ( buf[j] >= '0' && buf[j] <= '8' ) { + buf[j]++; + ro = 0; + } + else if ( buf[j] == '9' ) { + buf[j] = '0'; + } + j++; + } + if ( ro == 1 ) + buf[i++] = '1'; + + buf[i] = 0; + + size -= precision; + if (!(type&(ZEROPAD+LEFT))) + { + while(size-->0) + f += ' '; + } + if (sign) + { + f += sign; + } + + if (!(type&(ZEROPAD+LEFT))) + while(size-->0) + { + f += ' '; + } + if (type & SPECIAL) { + } + + if (!(type & LEFT)) + while (size-- > 0) + { + f += c; + } + + tmp = buf; + if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) + { + j = 0; + while ( j < i && ( *tmp == '0' || *tmp == '.' )) + { + tmp++; + i--; + } + } +// else +// while (i < precision--) +// putc('0', f); + while (i-- > 0) + { + f += tmp[i]; + } + while (size-- > 0) + { + f += ' '; + } + } + return true; +} + + +static bool numberfl(std::string& f, long double __n, char exp_sign, int size, int precision, int type) +{ + long double exponent = 0.0; + long double e; + long ie; + + //int x; + char *buf, *tmp; + int i = 0; + int j = 0; + //int k = 0; + + long double frac, intr; + long double p; + char sign; + char c; + char ro = 0; + + int result; + + union + { + long double* __n; + ieee_long_double_t* n; + } n; + + n.__n = &__n; + + if ( exp_sign == 'g' || exp_sign == 'G' || exp_sign == 'e' || exp_sign == 'E' ) { + ie = ((unsigned int)n.n->exponent - (unsigned int)0x3fff); + exponent = ie/3.321928; + } + + if ( exp_sign == 'g' || exp_sign == 'G' ) { + type |= ZEROTRUNC; + if ( exponent < -4 || fabs(exponent) >= precision ) + exp_sign -= 2; // g -> e and G -> E + } + + if ( exp_sign == 'e' || exp_sign == 'E' ) { + frac = modfl(exponent,&e); + if ( frac > 0.5 ) + e++; + else if ( frac < -0.5 ) + e--; + + result = numberf(f,__n/powl(10.0L,e),'f',size-4, precision, type); + if (result < 0) + return false; + f += exp_sign; + size--; + ie = (long)e; + type = LEFT | PLUS; + if ( ie < 0 ) + type |= SIGN; + + result = number(f,ie, 10,2, 2,type ); + if (result < 0) + return false; + return true; + } + + if ( exp_sign == 'f' ) + { + + buf = (char*)alloca(4096); + if (type & LEFT) + { + type &= ~ZEROPAD; + } + + c = (type & ZEROPAD) ? '0' : ' '; + sign = 0; + if (type & SIGN) + { + if (__n < 0) + { + sign = '-'; + __n = fabs(__n); + size--; + } else if (type & PLUS) + { + sign = '+'; + size--; + } else if (type & SPACE) + { + sign = ' '; + size--; + } + } + + frac = modfl(__n,&intr); + + // # flags forces a . and prevents trucation of trailing zero's + if ( precision > 0 ) + { + //frac = modfl(__n,&intr); + + i = precision-1; + while ( i >= 0 ) + { + frac*=10.0L; + frac = modfl((long double)frac, &p); + buf[i] = (int)p + '0'; + i--; + } + i = precision; + size -= precision; + + ro = 0; + if ( frac > 0.5 ) + { + ro = 1; + } + + if ( precision >= 1 || type & SPECIAL) + { + buf[i++] = '.'; + size--; + } + } + + if ( intr == 0.0 ) + { + buf[i++] = '0'; + size--; + } + else + { + while ( intr > 0.0 ) + { + p=intr; + intr/=10.0L; + modfl(intr, &intr); + + p -= 10.0L*intr; + + buf[i++] = (int)p + '0'; + size--; + } + } + + j = 0; + while ( j < i && ro == 1) { + if ( buf[j] >= '0' && buf[j] <= '8' ) + { + buf[j]++; + ro = 0; + } + else if ( buf[j] == '9' ) + { + buf[j] = '0'; + } + j++; + } + if ( ro == 1 ) + buf[i++] = '1'; + + buf[i] = 0; + + size -= precision; + if (!(type&(ZEROPAD+LEFT))) + { + while(size-->0) + f += ' '; + } + if (sign) + { + f += sign; + } + + if (!(type&(ZEROPAD+LEFT))) + { + while(size-->0) + f += ' '; + } + if (type & SPECIAL) { + } + + if (!(type & LEFT)) + while (size-- > 0) + { + f += c; + } + tmp = buf; + if ( type & ZEROTRUNC && ((type & SPECIAL) != SPECIAL) ) + { + j = 0; + while ( j < i && ( *tmp == '0' || *tmp == '.' )) + { + tmp++; + i--; + } + } +// else +// while (i < precision--) +// putc( '0', f); + while (i-- > 0) + { + f += tmp[i]; + } + while (size-- > 0) + { + f += ' '; + } + } + return true; +} + +static int string(std::string& f, const char* s, int len, int field_width, int precision, int flags) +{ + int i, done = 0; + if (s == NULL) + { + s = ""; + len = 6; + } + else + { + if (len == -1) + { + len = 0; + while ((unsigned int)len < (unsigned int)precision && s[len]) + len++; + } + else + { + if ((unsigned int)len > (unsigned int)precision) + len = precision; + } + } + if (!(flags & LEFT)) + while (len < field_width--) + { + f += ' '; + done++; + } + for (i = 0; i < len; ++i) + { + f += *s++; + done++; + } + while (len < field_width--) + { + f += ' '; + done++; + } + return done; +} + +static int stringw(std::string& f, const wchar_t* sw, int len, int field_width, int precision, int flags) +{ + int i, done = 0; + if (sw == NULL) + { + sw = L""; + len = 6; + } + else + { + if (len == -1) + { + len = 0; + while ((unsigned int)len < (unsigned int)precision && sw[len]) + len++; + } + else + { + if ((unsigned int)len > (unsigned int)precision) + len = precision; + } + } + if (!(flags & LEFT)) + while (len < field_width--) + { + f += ' '; + done++; + } + for (i = 0; i < len; ++i) + { +#define MY_MB_CUR_MAX 1 + char mb[MY_MB_CUR_MAX]; + int mbcount, j; + mbcount = wctomb(mb, *sw++); + if (mbcount <= 0) + { + break; + } + for (j = 0; j < mbcount; j++) + { + f += mb[j]; + done++; + } + } + while (len < field_width--) + { + f += ' '; + done++; + } + return done; +} + +#define _isnanl _isnan +#define _finitel _finite + +std::string ssvprintf ( const char *fmt, va_list args ) +{ + ULONGLONG num; + int base; + long double _ldouble; + double _double; + const char *s; + const unsigned short* sw; + int result; + std::string f; + + int flags; /* flags to number() */ + + int field_width; /* width of output field */ + int precision; /* min. # of digits for integers; max + number of chars for from string */ + int qualifier = 0; /* 'h', 'l', 'L' or 'I64' for integer fields */ + + for (; *fmt ; ++fmt) + { + if (*fmt != '%') + { + f += *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= LEFT; goto repeat; + case '+': flags |= PLUS; goto repeat; + case ' ': flags |= SPACE; goto repeat; + case '#': flags |= SPECIAL; goto repeat; + case '0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if (isdigit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (isdigit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + ++fmt; + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = 0; + // %Z can be just stand alone or as size_t qualifier + if ( *fmt == 'Z' ) { + qualifier = *fmt; + switch ( *(fmt+1)) { + case 'o': + case 'b': + case 'X': + case 'x': + case 'd': + case 'i': + case 'u': + ++fmt; + break; + default: + break; + } + } else if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'w') { + qualifier = *fmt; + ++fmt; + } else if (*fmt == 'I' && *(fmt+1) == '6' && *(fmt+2) == '4') { + qualifier = *fmt; + fmt += 3; + } + + // go fine with ll instead of L + if ( *fmt == 'l' ) { + ++fmt; + qualifier = 'L'; + } + + /* default base */ + base = 10; + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + { + f += ' '; + } + if (qualifier == 'l' || qualifier == 'w') + { + f += (char)(unsigned char)(wchar_t) va_arg(args,int); + } + else + { + f += (char)(unsigned char) va_arg(args,int); + } + while (--field_width > 0) + { + f += ' '; + } + continue; + + case 'C': + if (!(flags & LEFT)) + while (--field_width > 0) + { + f += ' '; + } + if (qualifier == 'h') + { + f += (char)(unsigned char) va_arg(args,int); + } + else + { + f += (char)(unsigned char)(wchar_t) va_arg(args,int); + } + while (--field_width > 0) + { + f += ' '; + } + continue; + + case 's': + if (qualifier == 'l' || qualifier == 'w') { + /* print unicode string */ + sw = va_arg(args, wchar_t *); + result = stringw(f, sw, -1, field_width, precision, flags); + } else { + /* print ascii string */ + s = va_arg(args, char *); + result = string(f, s, -1, field_width, precision, flags); + } + if (result < 0) + { + assert(!"TODO FIXME handle error better"); + return f; + } + continue; + + case 'S': + if (qualifier == 'h') { + /* print ascii string */ + s = va_arg(args, char *); + result = string(f, s, -1, field_width, precision, flags); + } else { + /* print unicode string */ + sw = va_arg(args, wchar_t *); + result = stringw(f, sw, -1, field_width, precision, flags); + } + if (result < 0) + { + assert(!"TODO FIXME handle error better"); + return f; + } + continue; + + /*case 'Z': + if (qualifier == 'w') { + // print counted unicode string + PUNICODE_STRING pus = va_arg(args, PUNICODE_STRING); + if ((pus == NULL) || (pus->Buffer == NULL)) { + sw = NULL; + len = -1; + } else { + sw = pus->Buffer; + len = pus->Length / sizeof(WCHAR); + } + result = stringw(f, sw, len, field_width, precision, flags); + } else { + // print counted ascii string + PANSI_STRING pas = va_arg(args, PANSI_STRING); + if ((pas == NULL) || (pas->Buffer == NULL)) { + s = NULL; + len = -1; + } else { + s = pas->Buffer; + len = pas->Length; + } + result = string(f, s, -1, field_width, precision, flags); + } + if (result < 0) + return -1; + continue;*/ + + case 'e': + case 'E': + case 'f': + case 'g': + case 'G': + if (qualifier == 'l' || qualifier == 'L' ) { + _ldouble = va_arg(args, long double); + + if ( _isnanl(_ldouble) ) + { + f += "Nan"; + } + else if ( !_finitel(_ldouble) ) + { + if ( _ldouble < 0 ) + f += "-Inf"; + else + f += "+Inf"; + } else { + if ( precision == -1 ) + precision = 6; + result = numberfl(f,_ldouble,*fmt,field_width,precision,flags); + if (result < 0) + { + assert(!"TODO FIXME handle error better"); + return f; + } + } + } else { + _double = (double)va_arg(args, double); + + if ( _isnan(_double) ) + { + f += "Nan"; + } + else if ( !_finite(_double) ) + { + if ( _double < 0 ) + f += "-Inf"; + else + f += "+Inf"; + } + else + { + if ( precision == -1 ) + precision = 6; + result = numberf(f,_double,*fmt,field_width,precision,flags); + if (result < 0) + { + assert(!"TODO FIXME handle error better"); + return f; + } + } + } + continue; + + case 'p': + if (field_width == -1) { + field_width = 2*sizeof(void *); + flags |= ZEROPAD; + } + result = number(f, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + if (result < 0) + { + assert(!"TODO FIXME handle error better"); + return f; + } + continue; + + case 'n': + if (qualifier == 'l') { + long * ip = va_arg(args, long *); + *ip = 0; + } else { + int * ip = va_arg(args, int *); + *ip = 0; + } + continue; + + /* integer number formats - set up the flags and "break" */ + case 'o': + base = 8; + break; + + case 'b': + base = 2; + break; + + case 'X': + flags |= LARGE; + case 'x': + base = 16; + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + break; + + default: + if (*fmt != '%') + { + f += '%'; + } + if (*fmt) + { + f += *fmt; + } + else + --fmt; + continue; + } + + if (qualifier == 'I') + num = va_arg(args, ULONGLONG); + else if (qualifier == 'l') { + if (flags & SIGN) + num = va_arg(args, long); + else + num = va_arg(args, unsigned long); + } + else if (qualifier == 'h') { + if (flags & SIGN) + num = va_arg(args, int); + else + num = va_arg(args, unsigned int); + } + else if (flags & SIGN) + num = va_arg(args, int); + else + num = va_arg(args, unsigned int); + result = number(f, num, base, field_width, precision, flags); + if (result < 0) + { + assert(!"TODO FIXME handle error better"); + return f; + } + } + //putc('\0',f); + return f; +} diff --git a/rosapps/games/ArchBlackmann/ssprintf.h b/rosapps/games/ArchBlackmann/ssprintf.h new file mode 100644 index 00000000000..aa04411a1e5 --- /dev/null +++ b/rosapps/games/ArchBlackmann/ssprintf.h @@ -0,0 +1,12 @@ +// ssprintf.h + +#ifndef SSPRINTF_H +#define SSPRINTF_H + +#include +#include + +std::string ssprintf ( const char* fmt, ... ); +std::string ssvprintf ( const char* fmt, va_list args ); + +#endif//SSPRINTF_H -- 2.17.1