├── ChangeLog ├── autogen.sh ├── AUTHORS ├── README ├── bootstrap ├── showerror.h ├── version.cpp ├── memory.h ├── edit.h ├── mbf.h ├── charset.h ├── runnerline.cpp ├── key.h ├── trace.h ├── dim.h ├── runnerline.h ├── directory.h ├── regexp.h ├── testdl.cpp ├── cursor.h ├── token.h ├── socket.h ├── dim.cpp ├── function.h ├── program.h ├── showerror.cpp ├── codeline.h ├── blassic.spec.in ├── element.cpp ├── var.h ├── dynamic.h ├── error.h ├── using.h ├── memory.cpp ├── filesocket.cpp ├── trace.cpp ├── sysvar.cpp ├── element.h ├── mbf.cpp ├── key.cpp ├── graphics.h ├── dynamic.cpp ├── util.h ├── directory.cpp ├── Makefile.am ├── gencharset.cpp ├── sysvar.h ├── file.h ├── function.cpp ├── blassic.h ├── token.cpp ├── error.cpp ├── socket.cpp ├── acinclude.m4 ├── regexp.cpp ├── filewindow.cpp ├── configure.ac ├── runnerline_print.cpp ├── keyword.cpp ├── keyword.h ├── INSTALL └── fileconsole.cpp /ChangeLog: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./bootstrap && ./configure $* 4 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notfound/Blassic/master/AUTHORS -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/notfound/Blassic/master/README -------------------------------------------------------------------------------- /bootstrap: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | aclocal -I . 4 | automake --add-missing --copy 5 | autoconf 6 | -------------------------------------------------------------------------------- /showerror.h: -------------------------------------------------------------------------------- 1 | // showerror.h 2 | // Revision 17-jul-2004 3 | 4 | void showlasterror (); 5 | void showlasterror (const char * str); 6 | 7 | // End of showerror.h 8 | -------------------------------------------------------------------------------- /version.cpp: -------------------------------------------------------------------------------- 1 | // version.cpp 2 | 3 | // The configure script will parse the version::* lines 4 | // to get the vesion number. 5 | 6 | #include "blassic.h" 7 | 8 | const unsigned short 9 | version::Major= 0, 10 | version::Minor= 10, 11 | version::Release= 3; 12 | 13 | // End of version.cpp 14 | -------------------------------------------------------------------------------- /memory.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_MEMORY_H 2 | #define INCLUDE_BLASSIC_MEMORY_H 3 | 4 | // memory.h 5 | // Revision 1-feb-2005 6 | 7 | #include "blassic.h" 8 | 9 | namespace blassic { 10 | 11 | namespace memory { 12 | 13 | size_t dyn_alloc (size_t memsize); 14 | void dyn_free (size_t mempos); 15 | void dyn_freeall (); 16 | 17 | } // namespace memory 18 | 19 | } // namespace blassic 20 | 21 | #endif 22 | 23 | // End of memory.h 24 | -------------------------------------------------------------------------------- /edit.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_EDIT_H 2 | #define INCLUDE_BLASSIC_EDIT_H 3 | 4 | // edit.h 5 | // Revision 23-jul-2004 6 | 7 | #include "blassic.h" 8 | #include "file.h" 9 | 10 | namespace blassic { 11 | 12 | namespace edit { 13 | 14 | bool editline (blassic::file::BlFile & bf, std::string & str, 15 | size_t npos, size_t inicol= 0, bool lineend= true); 16 | 17 | } // namespace blassic 18 | 19 | } // namespace edit 20 | 21 | #endif 22 | 23 | // End of edit.h 24 | -------------------------------------------------------------------------------- /mbf.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_MBF_H 2 | #define INCLUDE_BLASSIC_MBF_H 3 | 4 | // mbf.h 5 | // Revision 7-feb-2005 6 | 7 | // Routines to convert from/to Microsoft Binary Format. 8 | 9 | 10 | #include 11 | 12 | 13 | namespace mbf { 14 | 15 | double mbf_s (const std::string & s); 16 | double mbf_d (const std::string & s); 17 | 18 | std::string to_mbf_s (double v); 19 | std::string to_mbf_d (double v); 20 | 21 | } // namespace mbf 22 | 23 | #endif 24 | 25 | // End of mbf.h 26 | -------------------------------------------------------------------------------- /charset.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_CHARSET_H 2 | #define INCLUDE_BLASSIC_CHARSET_H 3 | 4 | // charset.h 5 | // Revision 13-jun-2006 6 | 7 | namespace charset { 8 | 9 | typedef unsigned char chardata [8]; 10 | typedef chardata chardataset [256]; 11 | 12 | extern const chardataset default_data; 13 | extern const chardataset cpc_data; 14 | extern const chardataset spectrum_data; 15 | extern const chardataset msx_data; 16 | 17 | extern chardataset data; 18 | 19 | extern const chardataset * default_charset; 20 | 21 | } 22 | 23 | #endif 24 | 25 | // End of charset.h 26 | -------------------------------------------------------------------------------- /runnerline.cpp: -------------------------------------------------------------------------------- 1 | // runnerline.cpp 2 | // Revision 31-jul-2004 3 | 4 | #include "runnerline.h" 5 | 6 | #include "trace.h" 7 | 8 | RunnerLine::RunnerLine (Runner & runner, const CodeLine & newcodeline) : 9 | runner (runner), 10 | codeline (newcodeline) 11 | { 12 | TRACEFUNC (tr, "RunnerLine::RunnerLine"); 13 | } 14 | 15 | RunnerLine::RunnerLine (Runner & runner) : 16 | runner (runner) 17 | { 18 | TRACEFUNC (tr, "RunnerLine::RunnerLine"); 19 | } 20 | 21 | RunnerLine::~RunnerLine () 22 | { 23 | TRACEFUNC (tr, "RunnerLine::~RunnerLine"); 24 | } 25 | 26 | // End of runnerline.cpp 27 | -------------------------------------------------------------------------------- /key.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_KEY_H 2 | #define INCLUDE_BLASSIC_KEY_H 3 | 4 | // key.h 5 | // Revision 7-feb-2005 6 | 7 | #include 8 | 9 | 10 | std::string string_from_key (unsigned int key); 11 | 12 | extern const std::string 13 | strPAGEUP, 14 | strPAGEDOWN, 15 | strEND, 16 | strHOME, 17 | strLEFT, 18 | strUP, 19 | strRIGHT, 20 | strDOWN, 21 | strINSERT, 22 | strDELETE, 23 | strF1, 24 | strF2, 25 | strF3, 26 | strF4, 27 | strF5, 28 | strF6, 29 | strF7, 30 | strF8, 31 | strF9, 32 | strF10, 33 | strF11, 34 | strF12, 35 | strENTER, 36 | strCLICK, 37 | strSCLICK, 38 | strRELEASE, 39 | strSRELEASE; 40 | 41 | #endif 42 | 43 | // End of key.h 44 | -------------------------------------------------------------------------------- /trace.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_TRACE_H 2 | #define INCLUDE_BLASSIC_TRACE_H 3 | 4 | // trace.h 5 | // Revision 7-feb-2005 6 | 7 | #include 8 | #include 9 | 10 | 11 | class TraceFunc { 12 | public: 13 | TraceFunc (const char * strFuncName); 14 | ~TraceFunc (); 15 | void message (const std::string & str); 16 | static void show (int); 17 | private: 18 | const char * strfunc; 19 | TraceFunc * * previous; 20 | TraceFunc * next; 21 | }; 22 | 23 | #ifndef NDEBUG 24 | 25 | #define TRACEFUNC(tr,name) \ 26 | TraceFunc tr (name) 27 | #define TRMESSAGE(tr,text) \ 28 | tr.message (text) 29 | 30 | #else 31 | 32 | #define TRACEFUNC(tr,name) 33 | #define TRMESSAGE(tr,text) 34 | 35 | #endif 36 | 37 | #endif 38 | 39 | // Fin de trace.h 40 | -------------------------------------------------------------------------------- /dim.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_DIM_H 2 | #define INCLUDE_BLASSIC_DIM_H 3 | 4 | // dim.h 5 | // Revision 6-jul-2004 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | class Dimension { 12 | public: 13 | void add (size_t n) { dim.push_back (n); } 14 | size_t size () const { return dim.size (); } 15 | bool empty () const { return dim.empty (); } 16 | size_t elements () const; 17 | size_t operator [] (size_t n) const { return dim [n]; } 18 | size_t evalpos (const Dimension & d) const; 19 | bool operator == (const Dimension & d) const 20 | { return dim == d.dim; } 21 | private: 22 | std::vector dim; 23 | }; 24 | 25 | std::ostream & operator << (std::ostream & os, const Dimension & d); 26 | 27 | #endif 28 | 29 | // Fin de dim.h 30 | -------------------------------------------------------------------------------- /runnerline.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_RUNNERLINE_H 2 | #define INCLUDE_BLASSIC_RUNNERLINE_H 3 | 4 | // runnerline.h 5 | // Revision 18-jul-2004 6 | 7 | #include "codeline.h" 8 | #include "function.h" 9 | #include "result.h" 10 | 11 | class Runner; 12 | class LocalLevel; 13 | 14 | class RunnerLine { 15 | public: 16 | RunnerLine (Runner & runner); 17 | RunnerLine (Runner & runner, const CodeLine & newcodeline); 18 | virtual ~RunnerLine (); 19 | 20 | CodeLine & getcodeline () { return codeline; } 21 | virtual void execute ()= 0; 22 | virtual ProgramPos getposactual () const= 0; 23 | virtual void callfn (Function & f, const std::string & fname, 24 | LocalLevel & ll, blassic::result::BlResult & result)= 0; 25 | protected: 26 | Runner & runner; 27 | CodeLine codeline; 28 | }; 29 | 30 | RunnerLine * newRunnerLine (Runner & runner, const CodeLine & newcodeline); 31 | 32 | #endif 33 | 34 | // End of runnerline.h 35 | -------------------------------------------------------------------------------- /directory.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_DIRECTORY_H 2 | #define INCLUDE_BLASSIC_DIRECTORY_H 3 | 4 | // directory.h 5 | // Revision 7-feb-2005 6 | 7 | 8 | #include 9 | 10 | #include "util.h" 11 | 12 | 13 | class Directory { 14 | public: 15 | Directory (); 16 | ~Directory (); 17 | std::string findfirst (const std::string & str); 18 | std::string findnext (); 19 | private: 20 | Directory (const Directory &); // Forbidden 21 | Directory operator = (const Directory &); // Forbidden 22 | class Internal; 23 | Internal * pin; 24 | //util::pimpl_ptr pin; 25 | }; 26 | 27 | void remove_file (const std::string & filename); 28 | void rename_file (const std::string & orig, const std::string & dest); 29 | 30 | void change_dir (const std::string & dirname); 31 | void make_dir (const std::string & dirname); 32 | void remove_dir (const std::string & dirname); 33 | 34 | void sleep_milisec (unsigned long n); 35 | 36 | #endif 37 | 38 | // End of directory.h 39 | -------------------------------------------------------------------------------- /regexp.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_REGEXP_H 2 | #define INCLUDE_BLASSIC_REGEXP_H 3 | 4 | // regexp.h 5 | // Revision 7-feb-2005 6 | 7 | 8 | #include 9 | 10 | //#include "runnerline.h" 11 | class RunnerLine; 12 | 13 | 14 | class Regexp { 15 | public: 16 | typedef std::string string; 17 | typedef string::size_type size_type; 18 | typedef unsigned int flag_t; 19 | static const flag_t FLAG_NOCASE= 1; 20 | static const flag_t FLAG_NOBEG= 2; 21 | static const flag_t FLAG_NOEND= 4; 22 | static const flag_t FLAG_NEWLINE= 8; 23 | 24 | Regexp (const string & exp, flag_t flags); 25 | ~Regexp (); 26 | size_type find (const string & searched, size_type init); 27 | string replace (const string & searched, size_type init, 28 | const string & replaceby); 29 | string replace (const string & searched, size_type init, 30 | RunnerLine & runnerline, const string & fname); 31 | private: 32 | class Internal; 33 | Internal * pin; 34 | }; 35 | 36 | #endif 37 | 38 | // End of regexp.h 39 | -------------------------------------------------------------------------------- /testdl.cpp: -------------------------------------------------------------------------------- 1 | // testdl.cpp 2 | 3 | #ifdef _Windows 4 | #define EXTERN extern "C" __declspec (dllexport) 5 | #else 6 | #define EXTERN extern "C" 7 | #endif 8 | 9 | #ifdef _Windows 10 | #include 11 | 12 | #ifdef __BORLANDC__ 13 | #pragma hdrstop 14 | #include 15 | // string (iterator, iterator) gives this warnig: 16 | #pragma warn -8012 17 | #else 18 | #error Compiler not tested. 19 | #endif 20 | 21 | #endif 22 | 23 | #include 24 | #include 25 | 26 | using std::string; 27 | 28 | #ifdef _Windows 29 | 30 | #pragma argsused 31 | int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*) 32 | { 33 | return 1; 34 | } 35 | 36 | #endif 37 | 38 | EXTERN int testfunc (int nparams, int * param) 39 | { 40 | if (nparams != 1) 41 | return 1; 42 | string * pstr= reinterpret_cast (param [0]); 43 | string nstr ( pstr->rbegin (), pstr->rend () ); 44 | // Do not use * pstr= nstr nor assign a string longer than * pstr. 45 | pstr->assign (nstr); 46 | return 0; 47 | } 48 | 49 | // Fin de testdl.cpp 50 | -------------------------------------------------------------------------------- /cursor.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_CURSOR_H 2 | #define INCLUDE_BLASSIC_CURSOR_H 3 | 4 | // cursor.h 5 | // Revision 7-feb-2005 6 | 7 | 8 | #include 9 | 10 | 11 | namespace cursor { 12 | 13 | void initconsole (); 14 | void quitconsole (); 15 | 16 | size_t getwidth (); 17 | 18 | void cursorvisible (); 19 | void cursorinvisible (); 20 | void showcursor (); 21 | void hidecursor (); 22 | 23 | void cls (); 24 | 25 | //void locate (int row, int col); 26 | void gotoxy (int x, int y); 27 | int getcursorx (); 28 | void movecharforward (); 29 | void movecharback (); 30 | void movecharforward (size_t n); 31 | void movecharback (size_t n); 32 | void movecharup (); 33 | void movechardown (); 34 | void movecharup (size_t n); 35 | void movechardown (size_t n); 36 | void savecursorpos (); 37 | void restorecursorpos (); 38 | 39 | void textcolor (int color); 40 | void textbackground (int color); 41 | 42 | std::string inkey (); 43 | std::string getkey (); 44 | bool pollin (); 45 | 46 | void clean_input (); 47 | 48 | void ring (); 49 | 50 | void set_title (const std::string & title); 51 | 52 | } // namespace cursor 53 | 54 | #endif 55 | 56 | // Fin de cursor.h 57 | -------------------------------------------------------------------------------- /token.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_TOKEN_H 2 | #define INCLUDE_BLASSIC_TOKEN_H 3 | 4 | // token.h 5 | // Revision 7-feb-2005 6 | 7 | 8 | #include "blassic.h" 9 | 10 | #include 11 | 12 | 13 | class Tokenizer { 14 | public: 15 | enum Type { Empty, EndLine, Blank, Plain, Literal, Integer }; 16 | Tokenizer (const std::string & source); 17 | 18 | // Members of token are public accessible for simplicity. 19 | // Use with care. 20 | class Token { 21 | public: 22 | Token () : 23 | type (Empty) 24 | { } 25 | Token (Type t) : 26 | type (t) 27 | { } 28 | Token (Type t, const std::string & str) : 29 | type (t), str (str) 30 | { } 31 | Token (BlInteger n) : 32 | type (Integer), n (n) 33 | { } 34 | Type type; 35 | std::string str; 36 | BlInteger n; 37 | }; 38 | Token get (); 39 | std::string getrest (); 40 | unsigned char peek (); 41 | private: 42 | unsigned char peeknospace (); 43 | unsigned char nextchar (); 44 | unsigned char nextcharnospace (); 45 | void ungetchar (); 46 | std::string str; 47 | std::string::size_type pos; 48 | const std::string::size_type limit; 49 | }; 50 | 51 | #endif 52 | 53 | // Fin de token.h 54 | -------------------------------------------------------------------------------- /socket.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_SOCKET_H 2 | #define INCLUDE_BLASSIC_SOCKET_H 3 | 4 | // socket.h 5 | // Revision 6-feb-2005 6 | 7 | #include 8 | #include 9 | 10 | #ifdef __BORLANDC__ 11 | #pragma warn -8026 12 | #endif 13 | 14 | class SocketError : public std::exception { 15 | public: 16 | SocketError (const std::string & nstr); 17 | SocketError (const std::string & nstr, int errnum); 18 | ~SocketError () throw () { } 19 | const char * what () const throw (); 20 | private: 21 | std::string str; 22 | static std::string strErr; 23 | }; 24 | 25 | class Socket { 26 | public: 27 | Socket (); 28 | Socket (const Socket & nsock); 29 | ~Socket (); 30 | Socket & operator = (const Socket & nsock); 31 | //TypeSocket handle (); 32 | bool eof (); 33 | std::string readline (); 34 | int read (char * str, int len); 35 | void write (const std::string & str); 36 | void write (const char * str, size_t len); 37 | protected: 38 | class Internal; 39 | Internal * in; 40 | }; 41 | 42 | class TcpSocket : public Socket { 43 | public: 44 | TcpSocket (); 45 | }; 46 | 47 | class TcpSocketClient : public TcpSocket { 48 | public: 49 | TcpSocketClient (const std::string & host, unsigned short port); 50 | }; 51 | 52 | #endif 53 | 54 | // End of socket.h 55 | -------------------------------------------------------------------------------- /dim.cpp: -------------------------------------------------------------------------------- 1 | // dim.cpp 2 | // Revision 14-oct-2003 3 | 4 | #include "dim.h" 5 | #include "error.h" 6 | 7 | #include 8 | 9 | class dim_calc { 10 | public: 11 | dim_calc () : r (1) { } 12 | void operator () (const size_t n) 13 | { r*= n + 1; } 14 | size_t value () { return r; } 15 | private: 16 | size_t r; 17 | }; 18 | 19 | size_t Dimension::elements () const 20 | { 21 | dim_calc r= std::for_each (dim.begin (), dim.end (), dim_calc () ); 22 | return r.value (); 23 | } 24 | 25 | size_t Dimension::evalpos (const Dimension & d) const 26 | { 27 | size_t n= size (); 28 | if (d.size () != n) 29 | throw ErrBadSubscript; 30 | size_t pos= d [0]; 31 | if (pos > dim [0]) 32 | throw ErrBadSubscript; 33 | for (size_t i= 1; i < n; ++i) 34 | { 35 | if (d [i] > dim [i] ) 36 | throw ErrBadSubscript; 37 | pos*= dim [i] + 1; 38 | pos+= d [i]; 39 | } 40 | return pos; 41 | } 42 | 43 | // Only for debug. 44 | 45 | std::ostream & operator << (std::ostream & os, const Dimension & d) 46 | { 47 | size_t s= d.size (); 48 | if (s == 0) 49 | os << "(empty)"; 50 | else 51 | { 52 | os << '('; 53 | for (size_t i= 0; i < s; ++i) 54 | { 55 | os << d [i]; 56 | if (i < s -1) 57 | os << ", "; 58 | } 59 | os << ')'; 60 | } 61 | return os; 62 | } 63 | 64 | // Fin de dim.cpp 65 | -------------------------------------------------------------------------------- /function.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_FUNCTION_H 2 | #define INCLUDE_BLASSIC_FUNCTION_H 3 | 4 | // function.h 5 | // Revision 7-feb-2005 6 | 7 | 8 | #include "codeline.h" 9 | 10 | #include 11 | 12 | 13 | class ParameterList { 14 | public: 15 | ParameterList (); 16 | ParameterList (const ParameterList & pl); 17 | ~ParameterList (); 18 | ParameterList & operator= (const ParameterList & pl); 19 | void push_back (const std::string & name); 20 | size_t size () const; 21 | //const std::string & operator [] (size_t n) const; 22 | std::string operator [] (size_t n) const; 23 | private: 24 | class Internal; 25 | Internal * pin; 26 | }; 27 | 28 | class Function { 29 | public: 30 | enum DefType { DefSingle, DefMulti }; 31 | Function (const std::string & strdef, const ParameterList & param); 32 | Function (ProgramPos posfn, const ParameterList & param); 33 | Function (const Function & f); 34 | ~Function (); 35 | Function & operator= (const Function &); 36 | DefType getdeftype () const; 37 | CodeLine & getcode (); 38 | ProgramPos getpos () const; 39 | const ParameterList & getparam (); 40 | static void clear (); 41 | void insert (const std::string & name); 42 | static Function & get (const std::string & name); 43 | private: 44 | class Internal; 45 | Internal * pin; 46 | }; 47 | 48 | #endif 49 | 50 | // Fin de function.h 51 | -------------------------------------------------------------------------------- /program.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_PROGRAM_H 2 | #define INCLUDE_BLASSIC_PROGRAM_H 3 | 4 | // program.h 5 | // Revision 31-jul-2004 6 | 7 | #include "blassic.h" 8 | #include "codeline.h" 9 | #include "file.h" 10 | 11 | class Program { 12 | public: 13 | Program (); 14 | virtual ~Program (); 15 | virtual BlChar * programptr ()= 0; 16 | virtual BlLineNumber getlabel (const std::string & str)= 0; 17 | virtual CodeLine getfirstline ()= 0; 18 | virtual void getnextline (CodeLine & codeline)= 0; 19 | virtual void getline (BlLineNumber num, CodeLine & codeline)= 0; 20 | virtual void getline (ProgramPos pos, CodeLine & codeline)= 0; 21 | virtual void insert (const CodeLine & codeline)= 0; 22 | virtual void deletelines 23 | (BlLineNumber iniline, BlLineNumber endline)= 0; 24 | virtual void listline (const CodeLine & codeline, 25 | blassic::file::BlFile & out) const= 0; 26 | virtual void list (BlLineNumber iniline, BlLineNumber endline, 27 | blassic::file::BlFile & out) const= 0; 28 | virtual void save (const std::string & name) const= 0; 29 | virtual void load (const std::string & name)= 0; 30 | virtual void load (std::istream & is)= 0; 31 | virtual void merge (const std::string & name, 32 | BlLineNumber inidel= LineNoDelete, 33 | BlLineNumber enddel= LineNoDelete 34 | )= 0; 35 | virtual void renew ()= 0; 36 | virtual void renum (BlLineNumber blnNew, BlLineNumber blnOld, 37 | BlLineNumber blnInc, BlLineNumber blnStop)= 0; 38 | private: 39 | Program (const Program &); // Prohibido 40 | Program & operator= (const Program &); // Prohibido 41 | }; 42 | 43 | Program * newProgram (); 44 | 45 | #endif 46 | 47 | // End of program.h 48 | -------------------------------------------------------------------------------- /showerror.cpp: -------------------------------------------------------------------------------- 1 | // showerror.cpp 2 | // Revision 9-jan-2005 3 | 4 | #include "showerror.h" 5 | 6 | #include "blassic.h" 7 | 8 | #include "error.h" 9 | 10 | #include "trace.h" 11 | 12 | #include 13 | using std::cerr; 14 | using std::endl; 15 | 16 | #ifdef BLASSIC_USE_WINDOWS 17 | 18 | #include 19 | 20 | void showlasterror () 21 | { 22 | TRACEFUNC (tr, "showlasterror"); 23 | 24 | if (! showdebuginfo () ) 25 | return; 26 | 27 | char * lpMsgBuf; 28 | DWORD r= FormatMessage ( 29 | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 30 | NULL, 31 | GetLastError (), 32 | MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), 33 | (char *) & lpMsgBuf, 34 | 0, 35 | NULL); 36 | if (r) 37 | { 38 | TRMESSAGE (tr, lpMsgBuf); 39 | CharToOemBuff (lpMsgBuf, lpMsgBuf, r); 40 | try 41 | { 42 | cerr << lpMsgBuf << endl; 43 | } 44 | catch (...) 45 | { 46 | r= 0; 47 | } 48 | LocalFree (lpMsgBuf); 49 | } 50 | if (! r) 51 | { 52 | static const char FAILED []= 53 | "FormatMessage failed, can't show error info"; 54 | TRMESSAGE (tr, FAILED); 55 | cerr << FAILED << endl; 56 | } 57 | } 58 | 59 | #else 60 | 61 | #include 62 | #include 63 | 64 | void showlasterror () 65 | { 66 | TRACEFUNC (tr, "showlasterror"); 67 | 68 | if (! showdebuginfo () ) 69 | return; 70 | 71 | const char * message= strerror (errno); 72 | TRMESSAGE (tr, message); 73 | cerr << message << endl; 74 | } 75 | 76 | #endif 77 | 78 | void showlasterror (const char * str) 79 | { 80 | TRACEFUNC (tr, "showlasterror (str)"); 81 | 82 | if (! showdebuginfo () ) 83 | return; 84 | 85 | cerr << str << ": "; 86 | showlasterror (); 87 | } 88 | 89 | // End of showerror.cpp 90 | -------------------------------------------------------------------------------- /codeline.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_CODELINE_H 2 | #define INCLUDE_BLASSIC_CODELINE_H 3 | 4 | // codeline.h 5 | // Revision 11-jul-2004 6 | 7 | #include "blassic.h" 8 | #include "keyword.h" 9 | 10 | class CodeLine { 11 | const BlChar * strcontent; 12 | BlLineNumber linenumber; 13 | BlLineLength len; 14 | bool owner; 15 | BlLineLength pos; 16 | BlChunk chk; 17 | BlCode lastcode; 18 | public: 19 | class Token { 20 | public: 21 | BlCode code; 22 | std::string str; 23 | BlInteger valueint; 24 | static BlNumber number (const std::string & str); 25 | BlNumber number () const; 26 | BlInteger integer () const { return valueint; } 27 | inline bool isendsentence () const 28 | { 29 | return code == ':' || 30 | code == keyENDLINE || 31 | code == keyELSE; 32 | } 33 | }; 34 | 35 | CodeLine (); 36 | CodeLine (const BlChar * str, BlLineNumber number, 37 | BlLineLength length); 38 | CodeLine (const CodeLine & old); 39 | ~CodeLine (); 40 | void assign (const BlChar * str, BlLineNumber number, 41 | BlLineLength length); 42 | CodeLine & operator= (const CodeLine & old); 43 | bool empty () const { return len == 0; } 44 | BlLineNumber number () const { return linenumber; } 45 | void setnumber (BlLineNumber n) { linenumber= n; } 46 | BlLineLength length () const { return len; } 47 | BlChunk chunk () const { return chk; } 48 | //BlChar * content () { return strcontent; } 49 | const BlChar * content () const { return strcontent; } 50 | BlCode actualcode () const { return lastcode; } 51 | Token getdata (); 52 | //Token gettoken (); 53 | void gettoken (Token & r); 54 | void gotochunk (BlChunk chknew); 55 | void scan (const std::string & line); 56 | }; 57 | 58 | #endif 59 | 60 | // Fin de codeline.h 61 | -------------------------------------------------------------------------------- /blassic.spec.in: -------------------------------------------------------------------------------- 1 | # RPM .spec file for blassic 2 | 3 | # Release number can be specified with rpm --define 'rel SOMETHING' ... 4 | # If no such --define is used, the release number is 1. 5 | # 6 | # Source archive's extension can be specified with rpm --define 'srcext .foo' 7 | # where .foo is the source archive's actual extension. 8 | # To compile an RPM from a .bz2 source archive, give the command 9 | # rpm -tb --define 'srcext .bz2' @PACKAGE@-@VERSION@.tar.bz2 10 | # 11 | %if %{?rel:0}%{!?rel:1} 12 | %define rel 1 13 | %endif 14 | %if %{?srcext:0}%{!?srcext:1} 15 | %define srcext .gz 16 | %endif 17 | 18 | Summary: Classic Basic interpreter 19 | Name: @PACKAGE@ 20 | Version: @VERSION@ 21 | Release: %{rel} 22 | Copyright: GPL 23 | Group: Development/Languages 24 | Source: %{name}-%{version}.tar%{srcext} 25 | Prefix: /usr 26 | BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root 27 | #Requires: svgalib >= 1.4.0 28 | 29 | %description 30 | Blassic is a classic Basic interpreter. The line numbers are 31 | mandatory, and it has PEEK & POKE. The main goal is to execute 32 | programs written in old interpreters, but it can be used as a 33 | scripting language. 34 | 35 | %package examples 36 | Summary: Example programs for the Blassic Basic interpreter 37 | Group: Development/Languages 38 | 39 | %description examples 40 | Example Basic programs for Blassic, the classic Basic interpreter. 41 | 42 | 43 | %prep 44 | %setup 45 | 46 | %build 47 | ./configure --prefix=%{prefix} --enable-installed-examples --disable-svgalib 48 | make CXXFLAGS="-DNDEBUG -O3" 49 | 50 | %install 51 | rm -fR $RPM_BUILD_ROOT 52 | make DESTDIR=$RPM_BUILD_ROOT install 53 | 54 | %clean 55 | rm -fR $RPM_BUILD_ROOT 56 | 57 | %files 58 | %defattr(-, root, root) 59 | %{prefix}/bin/@PACKAGE@ 60 | 61 | %files examples 62 | %defattr(-, root, root) 63 | %{prefix}/share/@PACKAGE@ 64 | -------------------------------------------------------------------------------- /element.cpp: -------------------------------------------------------------------------------- 1 | // element.cpp 2 | // Revision 8-jan-2005 3 | 4 | #include "element.h" 5 | 6 | #include "var.h" 7 | #include "trace.h" 8 | 9 | ForElementNumber::ForElementNumber (const std::string & nvar, 10 | ProgramPos pos, 11 | BlNumber initial, BlNumber nmax, BlNumber nstep) : 12 | ForElement (nvar, pos), 13 | max (nmax), 14 | step (nstep) 15 | { 16 | varaddr= addrvarnumber (nvar); 17 | * varaddr= initial; 18 | } 19 | 20 | ForElementNumberInc::ForElementNumberInc (const std::string & var, 21 | ProgramPos pos, 22 | BlNumber initial, BlNumber max, BlNumber step) : 23 | ForElementNumber (var, pos, initial, max, step) 24 | { 25 | //TRACEFUNC (tr, "ForElementNumberInc::ForElementNumberInc"); 26 | } 27 | 28 | bool ForElementNumberInc::next () 29 | { 30 | * varaddr+= step; 31 | return * varaddr <= max; 32 | } 33 | 34 | ForElementNumberDec::ForElementNumberDec (const std::string & var, 35 | ProgramPos pos, 36 | BlNumber initial, BlNumber max, BlNumber step) : 37 | ForElementNumber (var, pos, initial, max, step) 38 | { 39 | //TRACEFUNC (tr, "ForElementNumberDec::ForElementNumberDec"); 40 | } 41 | 42 | bool ForElementNumberDec::next () 43 | { 44 | * varaddr+= step; 45 | return * varaddr >= max; 46 | } 47 | 48 | ForElementInteger::ForElementInteger (const std::string & nvar, 49 | ProgramPos pos, 50 | BlInteger initial, BlInteger nmax, BlInteger nstep) : 51 | ForElement (nvar, pos), 52 | max (nmax), 53 | step (nstep) 54 | { 55 | varaddr= addrvarinteger (nvar); 56 | * varaddr= initial; 57 | } 58 | 59 | ForElementIntegerInc::ForElementIntegerInc (const std::string & var, 60 | ProgramPos pos, 61 | BlInteger initial, BlInteger max, BlInteger step) : 62 | ForElementInteger (var, pos, initial, max, step) 63 | { 64 | //TRACEFUNC (tr, "ForElementIntegerInc::ForElementIntegerInc"); 65 | } 66 | 67 | bool ForElementIntegerInc::next () 68 | { 69 | * varaddr+= step; 70 | return * varaddr <= max; 71 | } 72 | 73 | ForElementIntegerDec::ForElementIntegerDec (const std::string & var, 74 | ProgramPos pos, 75 | BlInteger initial, BlInteger max, BlInteger step) : 76 | ForElementInteger (var, pos, initial, max, step) 77 | { 78 | //TRACEFUNC (tr, "ForElementIntegerDec::ForElementIntegerDec"); 79 | } 80 | 81 | bool ForElementIntegerDec::next () 82 | { 83 | * varaddr+= step; 84 | return * varaddr >= max; 85 | } 86 | 87 | // End of element.cpp 88 | -------------------------------------------------------------------------------- /var.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_VAR_H 2 | #define INCLUDE_BLASSIC_VAR_H 3 | 4 | // var.h 5 | // Revision 8-jan-2005 6 | 7 | #include "blassic.h" 8 | #include "dim.h" 9 | 10 | // Now defined in blassic.h to reduce dependencies. 11 | 12 | //enum VarType { VarUndef, VarNumber, VarString, VarInteger }; 13 | 14 | //inline bool is_numeric_type (VarType v) 15 | //{ return v == VarNumber || v == VarInteger; } 16 | 17 | 18 | struct VarPointer { 19 | VarType type; 20 | union { 21 | BlNumber * pnumber; 22 | BlInteger * pinteger; 23 | std::string * pstring; 24 | }; 25 | std::string::size_type from, to; 26 | }; 27 | 28 | VarType typeofvar (const std::string & name); 29 | 30 | void definevar (VarType type, char c); 31 | void definevar (VarType type, char cfrom, char cto); 32 | 33 | void clearvars (); 34 | void assignvarnumber (const std::string & name, BlNumber value); 35 | void assignvarinteger (const std::string & name, BlInteger value); 36 | void assignvarstring (const std::string & name, const std::string & value); 37 | 38 | BlNumber evaluatevarnumber (const std::string & name); 39 | BlInteger evaluatevarinteger (const std::string & name); 40 | std::string evaluatevarstring (const std::string & name); 41 | 42 | BlNumber * addrvarnumber (const std::string & name); 43 | BlInteger * addrvarinteger (const std::string & name); 44 | std::string * addrvarstring (const std::string & name); 45 | 46 | void dimvarnumber (const std::string & name, const Dimension & d); 47 | void dimvarinteger (const std::string & name, const Dimension & d); 48 | void dimvarstring (const std::string & name, const Dimension & d); 49 | 50 | void erasevarnumber (const std::string & name); 51 | void erasevarinteger (const std::string & name); 52 | void erasevarstring (const std::string & name); 53 | 54 | BlNumber valuedimnumber (const std::string & name, const Dimension & d); 55 | BlInteger valuediminteger (const std::string & name, const Dimension & d); 56 | std::string valuedimstring (const std::string & name, const Dimension & d); 57 | 58 | void assigndimnumber (const std::string & name, const Dimension & d, 59 | BlNumber value); 60 | void assigndiminteger (const std::string & name, const Dimension & d, 61 | BlInteger value); 62 | void assigndimstring (const std::string & name, const Dimension & d, 63 | const std::string & value); 64 | 65 | BlNumber * addrdimnumber (const std::string & name, const Dimension & d); 66 | BlInteger * addrdiminteger (const std::string & name, const Dimension & d); 67 | std::string * addrdimstring (const std::string & name, const Dimension & d); 68 | 69 | #endif 70 | 71 | // Fin de var.h 72 | -------------------------------------------------------------------------------- /dynamic.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_DYNAMIC_H 2 | #define INCLUDE_BLASSIC_DYNAMIC_H 3 | 4 | // dynamic.h 5 | // Revision 7-feb-2005 6 | 7 | 8 | #include "blassic.h" 9 | 10 | #include 11 | 12 | //#if defined __WIN32__ || defined __CYGWIN__ || defined __MINGW32__ 13 | 14 | #ifdef BLASSIC_USE_WINDOWS 15 | 16 | typedef __declspec (dllimport) int (* DynamicUsrFunc) 17 | (int nparams, int * param); 18 | 19 | #else 20 | 21 | typedef int (* DynamicUsrFunc) (int nparams, int * param); 22 | 23 | #endif 24 | 25 | 26 | class DynamicHandle { 27 | public: 28 | DynamicHandle (); 29 | DynamicHandle (const std::string & name); 30 | void assign (const std::string & name); 31 | ~DynamicHandle (); 32 | DynamicUsrFunc addr (const std::string & str); 33 | private: 34 | class Internal; 35 | Internal * pin; 36 | }; 37 | 38 | #if 0 39 | 40 | #if (defined __unix__ || defined __linux__ || defined __NetBSD__) && \ 41 | ! defined __CYGWIN__ 42 | // Kylix defines only __linux__ 43 | 44 | #ifdef __hpux__ 45 | 46 | #include 47 | 48 | typedef shl_t DynamicHandle; 49 | 50 | inline DynamicHandle dynamicload (const std::string & str) 51 | { return shl_load (str.c_str (), BIND_DEFERRED, 0); } 52 | 53 | inline void * dynamicaddr (DynamicHandle & handle, const std::string & str) 54 | { 55 | void * value; 56 | if (shl_findsym (& handle, str.c_str (), TYPE_UNDEFINED, & value) == 0) 57 | return value; 58 | else return NULL; 59 | } 60 | 61 | inline void dynamicclose (DynamicHandle handle) 62 | { shl_unload (handle); } 63 | 64 | #else 65 | 66 | #include 67 | 68 | typedef void * DynamicHandle; 69 | 70 | inline DynamicHandle dynamicload (const std::string & str) 71 | { return dlopen (str.c_str (), RTLD_LAZY); } 72 | 73 | inline void * dynamicaddr (DynamicHandle handle, const std::string & str) 74 | { return dlsym (handle, str.c_str () ); } 75 | 76 | inline void dynamicclose (DynamicHandle handle) 77 | { dlclose (handle); } 78 | 79 | #endif 80 | 81 | #elif defined __WIN32__ || defined __CYGWIN__ 82 | 83 | #include 84 | #undef min 85 | #undef max 86 | 87 | typedef HMODULE DynamicHandle; 88 | 89 | inline DynamicHandle dynamicload (const std::string & str) 90 | { return LoadLibrary (str.c_str () ); } 91 | 92 | inline void * dynamicaddr (DynamicHandle handle, const std::string & str) 93 | { 94 | return (void *) GetProcAddress (handle, str.c_str () ); 95 | } 96 | 97 | inline void dynamicclose (DynamicHandle handle) 98 | { FreeLibrary (handle); } 99 | 100 | #else 101 | #error Unknown operating system 102 | #endif 103 | 104 | #endif 105 | 106 | #endif 107 | 108 | // Fin de dymanic.h 109 | -------------------------------------------------------------------------------- /error.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_ERROR_H 2 | #define INCLUDE_BLASSIC_ERROR_H 3 | 4 | // error.h 5 | // Revision 7-feb-2005 6 | 7 | 8 | #include "blassic.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | const BlErrNo 15 | ErrNoError= 0, 16 | ErrSyntax= 1, 17 | ErrMismatch= 2, 18 | ErrGosubWithoutReturn= 3, 19 | ErrReturnWithoutGosub= 4, 20 | ErrNextWithoutFor= 5, 21 | ErrNotImplemented= 6, 22 | ErrDivZero= 7, 23 | ErrDataExhausted= 8, 24 | ErrInvalidCommand= 9, 25 | ErrPolite= 10, 26 | ErrBadSubscript= 11, 27 | ErrOutMemory= 12, 28 | ErrAlreadyDim= 13, 29 | ErrNoContinue= 14, 30 | ErrFileNumber= 15, 31 | ErrFileMode= 16, 32 | ErrFileAlreadyOpen= 17, 33 | ErrFileRead= 18, 34 | ErrFileWrite= 19, 35 | ErrUntilWithoutRepeat= 20, 36 | ErrWendWithoutWhile= 21, 37 | ErrWhileWithoutWend= 22, 38 | ErrBlassicInternal= 23, 39 | ErrNoDynamicLibrary= 24, 40 | ErrNoDynamicSymbol= 25, 41 | ErrCannotResume= 26, 42 | ErrNoLabel= 27, 43 | ErrMisplacedLocal= 28, 44 | ErrFieldOverflow= 29, 45 | ErrFileNotFound= 30, 46 | ErrLineExhausted= 31, 47 | ErrFunctionNoDefined= 32, 48 | ErrIncompleteDef= 33, 49 | ErrInvalidDirect= 34, 50 | ErrBadRecord= 35, 51 | ErrFunctionCall= 36, 52 | ErrSocket= 37, 53 | ErrRenameFile= 38, 54 | ErrOperatingSystem= 39, 55 | ErrPastEof= 40, 56 | ErrNoGraphics= 41, 57 | ErrImproperArgument= 42, 58 | ErrDomain= 43, 59 | ErrRange= 44, 60 | ErrLineNotExist= 45, 61 | ErrFnRecursion= 46, 62 | ErrOverflow= 48, 63 | ErrRegexp= 49, 64 | ErrDynamicUnsupported= 50, 65 | ErrRepeatWithoutUntil= 51, 66 | ErrUnexpectedFnEnd= 52, 67 | ErrNoFnEnd= 53, 68 | ErrDuplicateLabel= 54, 69 | ErrNoTeDejo= 55; 70 | 71 | class BlError { 72 | public: 73 | BlError (); 74 | BlError (BlErrNo nerr); 75 | BlError (BlErrNo nerr, ProgramPos npos); 76 | void clear (); 77 | void set (BlErrNo nerr, ProgramPos npos); 78 | void seterr (BlErrNo nerr); 79 | BlErrNo geterr () const; 80 | ProgramPos getpos () const; 81 | friend std::ostream & operator << (std::ostream & os, 82 | const BlError & be); 83 | private: 84 | BlErrNo err; 85 | ProgramPos pos; 86 | }; 87 | 88 | class BlBreak { }; 89 | 90 | class BlBreakInPos { 91 | ProgramPos pos; 92 | public: 93 | BlBreakInPos (ProgramPos pos); 94 | ProgramPos getpos () const; 95 | }; 96 | 97 | std::ostream & operator << (std::ostream & os, const BlBreakInPos & bbip); 98 | 99 | std::string ErrStr (BlErrNo err); 100 | 101 | bool showdebuginfo (); 102 | 103 | #endif 104 | 105 | // Fin de error.h 106 | -------------------------------------------------------------------------------- /using.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_USING_H 2 | #define INCLUDE_BLASSIC_USING_H 3 | 4 | // using.h 5 | // Revision 7-feb-2005 6 | 7 | #include "error.h" 8 | #include "file.h" 9 | 10 | #include 11 | #include 12 | 13 | 14 | class Using { 15 | protected: 16 | Using () { } 17 | public: 18 | virtual ~Using (); 19 | virtual Using * clone () const= 0; 20 | virtual bool isliteral () const; 21 | virtual void putliteral (blassic::file::BlFile &) const= 0; 22 | virtual void putnumeric (blassic::file::BlFile &, BlNumber) const; 23 | virtual void putstring (blassic::file::BlFile &, 24 | const std::string &) const; 25 | }; 26 | 27 | class UsingLiteral : public Using { 28 | public: 29 | UsingLiteral (std::istream & is); 30 | UsingLiteral (std::istream & is, const std::string & strinit); 31 | UsingLiteral (const std::string & strinit); 32 | UsingLiteral * clone () const 33 | { return new UsingLiteral (* this); } 34 | bool isliteral () const; 35 | const std::string & str () const { return s; } 36 | void addstr (const std::string & stradd); 37 | void putliteral (blassic::file::BlFile & out) const; 38 | void putnumeric (blassic::file::BlFile &, BlNumber) const; 39 | void putstring (blassic::file::BlFile &, const std::string &) const; 40 | private: 41 | std::string s; 42 | void init (std::istream & is); 43 | }; 44 | 45 | class UsingNumeric : public Using { 46 | public: 47 | UsingNumeric (std::istream & is, std::string & tail); 48 | UsingNumeric * clone () const 49 | { return new UsingNumeric (* this); } 50 | const std::string & str () const { return s; } 51 | bool isvalid () const { return ! invalid; } 52 | void putliteral (blassic::file::BlFile &) const; 53 | void putnumeric (blassic::file::BlFile & out, BlNumber n) const; 54 | private: 55 | bool invalid; 56 | std::string s; 57 | size_t digit, decimal, scientific; 58 | bool milliards, putsign, signatend, blankpositive; 59 | bool asterisk, dollar, pound, euro; 60 | }; 61 | 62 | class UsingString : public Using { 63 | public: 64 | UsingString (std::istream & is); 65 | UsingString * clone () const 66 | { return new UsingString (* this); } 67 | void putliteral (blassic::file::BlFile &) const; 68 | void putstring (blassic::file::BlFile & out, 69 | const std::string & str) const; 70 | private: 71 | size_t n; 72 | }; 73 | 74 | class VectorUsing 75 | { 76 | public: 77 | VectorUsing (); 78 | ~VectorUsing (); 79 | size_t size () const { return v.size (); } 80 | bool empty () const { return v.empty (); } 81 | Using * & back () { return v.back (); } 82 | Using * & operator [] (size_t i) { return v [i]; } 83 | void push_back (const Using & u); 84 | private: 85 | VectorUsing (const VectorUsing &); // Forbidden 86 | VectorUsing & operator = (const VectorUsing &); // Forbidden 87 | static void delete_it (const Using * u) { delete u; } 88 | 89 | std::vector v; 90 | }; 91 | 92 | void parseusing (const std::string & str, VectorUsing & vu); 93 | 94 | #endif 95 | 96 | // End of using.h 97 | -------------------------------------------------------------------------------- /memory.cpp: -------------------------------------------------------------------------------- 1 | // memory.cpp 2 | // Revision 24-apr-2009 3 | 4 | #include "memory.h" 5 | 6 | #include "blassic.h" 7 | #include "error.h" 8 | #include "trace.h" 9 | 10 | //#ifdef HAVE_SYS_MMAN_H 11 | #ifdef HAVE_MMAP 12 | 13 | #include 14 | 15 | #if ! defined MAP_ANON 16 | 17 | #if defined MAP_ANONYMOUS 18 | 19 | #define MAP_ANON MAP_ANONYMOUS 20 | 21 | #else 22 | 23 | #error "Don't know how to flag anonymous map." 24 | 25 | #endif 26 | 27 | #endif 28 | 29 | #endif 30 | // HAVE_SYS_MMAN_H 31 | 32 | #include 33 | using std::cerr; 34 | using std::endl; 35 | 36 | #include 37 | #include 38 | 39 | //#include 40 | #include 41 | 42 | namespace { 43 | 44 | //typedef std::set memused_t; 45 | typedef std::map memused_t; 46 | 47 | memused_t memused; 48 | 49 | #ifdef HAVE_SYS_MMAN_H 50 | 51 | void do_munmap (void * start, size_t length) 52 | { 53 | TRACEFUNC (tr, "do_munmap"); 54 | 55 | int r= munmap (start, length); 56 | if (r != 0) 57 | { 58 | const char * errormessage= strerror (errno); 59 | TRMESSAGE (tr, std::string ("munmap failed: ") + errormessage); 60 | if (showdebuginfo () ) 61 | cerr << "munmap (" << start << ", " << 62 | length << ") failed: " << errormessage << 63 | endl; 64 | } 65 | } 66 | 67 | #endif 68 | 69 | } // namespace 70 | 71 | size_t blassic::memory::dyn_alloc (size_t memsize) 72 | { 73 | TRACEFUNC (tr, "memory::alloc"); 74 | 75 | if (memsize == 0) 76 | throw ErrFunctionCall; 77 | 78 | #ifndef HAVE_SYS_MMAN_H 79 | 80 | void * aux= malloc (memsize); 81 | 82 | #else 83 | 84 | void * aux= mmap (NULL, memsize, PROT_READ | PROT_WRITE | PROT_EXEC, 85 | MAP_PRIVATE | MAP_ANON, -1, 0); 86 | if (aux == (void *) -1) 87 | aux= NULL; 88 | 89 | #endif 90 | 91 | if (aux == NULL) 92 | { 93 | if (showdebuginfo () ) 94 | cerr << "Failed allocation of " << memsize << 95 | " bytes: " << strerror (errno) << endl; 96 | throw ErrOutMemory; 97 | } 98 | 99 | //memused.insert (aux); 100 | memused [aux]= memsize; 101 | return reinterpret_cast (aux); 102 | } 103 | 104 | void blassic::memory::dyn_free (size_t mempos) 105 | { 106 | TRACEFUNC (tr, "memory::free"); 107 | 108 | void * aux= reinterpret_cast (mempos); 109 | memused_t::iterator it= memused.find (aux); 110 | if (it == memused.end () ) 111 | { 112 | if (showdebuginfo () ) 113 | cerr << "Trying to free address " << mempos << 114 | " but is not allocated" << endl; 115 | throw ErrFunctionCall; 116 | } 117 | 118 | #ifdef HAVE_SYS_MMAN_H 119 | 120 | size_t memsize= it->second; 121 | 122 | #endif 123 | 124 | memused.erase (it); 125 | 126 | #ifndef HAVE_SYS_MMAN_H 127 | 128 | ::free (aux); 129 | 130 | #else 131 | 132 | //munmap (aux, memsize); 133 | do_munmap (aux, memsize); 134 | 135 | #endif 136 | } 137 | 138 | void blassic::memory::dyn_freeall () 139 | { 140 | TRACEFUNC (tr, "memory::freeall"); 141 | 142 | bool something= false; 143 | while (! memused.empty () ) 144 | { 145 | something= true; 146 | memused_t::iterator it= memused.begin (); 147 | 148 | #ifndef HAVE_SYS_MMAN_H 149 | 150 | ::free (it->first); 151 | 152 | #else 153 | 154 | //munmap (it->first, it->second); 155 | do_munmap (it->first, it->second); 156 | 157 | #endif 158 | 159 | memused.erase (it); 160 | } 161 | 162 | if (! something) 163 | TRMESSAGE (tr, "Nothing to free"); 164 | } 165 | 166 | // End of memory.cpp 167 | -------------------------------------------------------------------------------- /filesocket.cpp: -------------------------------------------------------------------------------- 1 | // filesocket.cpp 2 | // Revision 9-jan-2005 3 | 4 | //#include "filesocket.h" 5 | #include "file.h" 6 | 7 | #include "socket.h" 8 | #include "util.h" 9 | 10 | #include "trace.h" 11 | 12 | namespace blassic { 13 | 14 | namespace file { 15 | 16 | class BlFileSocket : public BlFile { 17 | public: 18 | BlFileSocket (const std::string & host, short port); 19 | ~BlFileSocket (); 20 | bool isfile () const { return true; } 21 | void getline (std::string & str, bool endline= true); 22 | bool eof (); 23 | void flush (); 24 | std::string read (size_t n); 25 | private: 26 | void outstring (const std::string & str); 27 | void outchar (char c); 28 | 29 | class Internal; 30 | Internal * pin; 31 | }; 32 | 33 | //*********************************************** 34 | // BlFileSocket::Internal 35 | //*********************************************** 36 | 37 | class BlFileSocket::Internal 38 | { 39 | TcpSocketClient socket; 40 | public: 41 | Internal (const std::string & host, short port); 42 | ~Internal (); 43 | void getline (std::string & str, bool endline); 44 | bool eof (); 45 | void flush (); 46 | std::string read (size_t n); 47 | void outstring (const std::string & str); 48 | void outchar (char c); 49 | private: 50 | Internal (const Internal &); // Forbidden 51 | void operator = (const Internal &); // Forbidden 52 | }; 53 | 54 | BlFileSocket::Internal::Internal (const std::string & host, short port) : 55 | socket (host, port) 56 | { 57 | } 58 | 59 | BlFileSocket::Internal::~Internal () 60 | { 61 | TRACEFUNC (tr, "BlFileSocke::Internal::~Internal"); 62 | } 63 | 64 | bool BlFileSocket::Internal::eof () 65 | { 66 | return socket.eof (); 67 | } 68 | 69 | void BlFileSocket::Internal::flush () 70 | { 71 | // There is no work to do. 72 | } 73 | 74 | void BlFileSocket::Internal::getline (std::string & str, bool) 75 | { 76 | str= socket.readline (); 77 | } 78 | 79 | std::string BlFileSocket::Internal::read (size_t n) 80 | { 81 | util::auto_buffer buf (n); 82 | int r= socket.read (buf, n); 83 | std::string result; 84 | if (r > 0) 85 | result.assign (buf, r); 86 | return result; 87 | } 88 | 89 | void BlFileSocket::Internal::outstring (const std::string & str) 90 | { 91 | socket.write (str); 92 | } 93 | 94 | void BlFileSocket::Internal::outchar (char c) 95 | { 96 | socket.write (& c, 1); 97 | } 98 | 99 | //*********************************************** 100 | // BlFileSocket 101 | //*********************************************** 102 | 103 | BlFile * newBlFileSocket (const std::string & host, short port) 104 | { 105 | return new BlFileSocket (host, port); 106 | } 107 | 108 | BlFileSocket::BlFileSocket (const std::string & host, short port) : 109 | BlFile (OpenMode (Input | Output) ), 110 | pin (new Internal (host, port) ) 111 | { } 112 | 113 | BlFileSocket::~BlFileSocket () 114 | { 115 | delete pin; 116 | } 117 | 118 | bool BlFileSocket::eof () 119 | { 120 | return pin->eof (); 121 | } 122 | 123 | void BlFileSocket::flush () 124 | { 125 | pin->flush (); 126 | } 127 | 128 | void BlFileSocket::getline (std::string & str, bool endline) 129 | { 130 | pin->getline (str, endline); 131 | } 132 | 133 | std::string BlFileSocket::read (size_t n) 134 | { 135 | return pin->read (n); 136 | } 137 | 138 | void BlFileSocket::outstring (const std::string & str) 139 | { 140 | pin->outstring (str); 141 | } 142 | 143 | void BlFileSocket::outchar (char c) 144 | { 145 | pin->outchar (c); 146 | } 147 | 148 | } // namespace file 149 | 150 | } // namespace blassic 151 | 152 | // End of filesocket.cpp 153 | -------------------------------------------------------------------------------- /trace.cpp: -------------------------------------------------------------------------------- 1 | // trace.cpp 2 | // Revision 7-feb-2005 3 | 4 | #include "trace.h" 5 | 6 | 7 | #if __BORLANDC__ >= 0x0560 8 | #pragma warn -8091 9 | #endif 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #ifdef HAVE_CSTDLIB 16 | #include 17 | #else 18 | #include 19 | #endif 20 | 21 | #include 22 | 23 | #include 24 | 25 | using std::cerr; 26 | using std::endl; 27 | using std::ostream; 28 | using std::ofstream; 29 | using std::string; 30 | 31 | 32 | namespace { 33 | 34 | ostream * pout= 0; 35 | bool flag= true; 36 | size_t indent= 0; 37 | 38 | TraceFunc * initial= NULL; 39 | TraceFunc * * lastpos= & initial; 40 | 41 | ostream * opentracefile (const char * str) 42 | { 43 | std::ofstream * pof= 44 | new ofstream (str, std::ios::app | std::ios::out); 45 | if (! pof->is_open () ) 46 | { 47 | cerr << "Error opening " << str << endl; 48 | delete pof; 49 | pof= 0; 50 | } 51 | return pof; 52 | } 53 | 54 | void showinfo (const char * strenterexit, const char * strfunc) 55 | { 56 | if (pout) 57 | { 58 | * pout << string (indent, ' ') << strenterexit << ' '; 59 | 60 | if (std::uncaught_exception () ) 61 | * pout << "(throwing) "; 62 | 63 | * pout << strfunc << endl; 64 | } 65 | } 66 | 67 | const char BAD_USE []= "Bad use of TraceFunc"; 68 | 69 | } // namespace 70 | 71 | TraceFunc::TraceFunc (const char * strFuncName) : 72 | strfunc (strFuncName), 73 | next (NULL) 74 | { 75 | if (flag) 76 | { 77 | flag= false; 78 | char * aux= getenv ("TRACEFUNC"); 79 | if (aux) 80 | { 81 | if (strcmp (aux, "-") == 0) 82 | pout= & std::cerr; 83 | else 84 | pout= opentracefile (aux); 85 | } 86 | } 87 | 88 | //tracelist.push_back (this); 89 | previous= lastpos; 90 | * lastpos= this; 91 | lastpos= & next; 92 | 93 | #if 0 94 | if (pout) 95 | { 96 | * pout << string (indent, ' ') << "Enter "; 97 | 98 | if (std::uncaught_exception () ) 99 | * pout << "(throwing) "; 100 | 101 | * pout << strfunc << endl; 102 | } 103 | #else 104 | showinfo ("Enter", strfunc); 105 | #endif 106 | ++indent; 107 | } 108 | 109 | TraceFunc::~TraceFunc () 110 | { 111 | --indent; 112 | 113 | #if 0 114 | if (pout) 115 | { 116 | * pout << string (indent, ' ') << "Exit "; 117 | 118 | if (std::uncaught_exception () ) 119 | * pout << "(throwing) "; 120 | 121 | * pout << strfunc << endl; 122 | } 123 | #else 124 | showinfo ("Exit", strfunc); 125 | #endif 126 | 127 | if (next != NULL) 128 | { 129 | cerr << BAD_USE << endl; 130 | abort (); 131 | } 132 | if (lastpos != & next) 133 | { 134 | //throw std::logic_error ("Bad use of TraceFunc"); 135 | cerr << BAD_USE << endl; 136 | abort (); 137 | } 138 | lastpos= previous; 139 | if (* lastpos != this) 140 | { 141 | cerr << BAD_USE << endl; 142 | abort (); 143 | } 144 | * lastpos= NULL; 145 | } 146 | 147 | void TraceFunc::message (const std::string & strMes) 148 | { 149 | if (pout) 150 | { 151 | * pout << string (indent, ' ') << strfunc; 152 | 153 | if (std::uncaught_exception () ) 154 | * pout << "(throwing) "; 155 | 156 | * pout << ": " << strMes << endl; 157 | } 158 | } 159 | 160 | void TraceFunc::show (int) 161 | { 162 | cerr << "\r\n"; 163 | 164 | if (initial == NULL) 165 | cerr << "TraceFunc: no calls."; 166 | else 167 | { 168 | cerr << "TraceFunc dump of calls: \r\n"; 169 | for (TraceFunc * act= initial; act != NULL; act= act->next) 170 | cerr << act->strfunc << "\r\n"; 171 | cerr << "TraceFunc dump ended."; 172 | } 173 | cerr << "\r\n"; 174 | } 175 | 176 | // Fin de trace.cpp 177 | -------------------------------------------------------------------------------- /sysvar.cpp: -------------------------------------------------------------------------------- 1 | // sysvar.cpp 2 | // Revision 6-feb-2005 3 | 4 | #include "sysvar.h" 5 | 6 | #include "charset.h" 7 | #include "trace.h" 8 | 9 | // For debugging. 10 | #include 11 | 12 | 13 | namespace { 14 | 15 | BlChar system_vars [blassic::sysvar::EndSysVar]; 16 | 17 | } // namespace 18 | 19 | 20 | size_t blassic::sysvar::address () 21 | { 22 | return reinterpret_cast (system_vars); 23 | } 24 | 25 | void blassic::sysvar::set (size_t var, BlChar value) 26 | { 27 | system_vars [var]= value; 28 | } 29 | 30 | void blassic::sysvar::set16 (size_t var, short value) 31 | { 32 | poke16 (system_vars + var, value); 33 | } 34 | 35 | void blassic::sysvar::set32 (size_t var, BlInteger value) 36 | { 37 | poke32 (system_vars + var, value); 38 | } 39 | 40 | BlChar blassic::sysvar::get (size_t var) 41 | { 42 | return system_vars [var]; 43 | } 44 | 45 | unsigned short blassic::sysvar::get16 (size_t var) 46 | { 47 | return static_cast (peek16 (system_vars + var) ); 48 | } 49 | 50 | unsigned long blassic::sysvar::get32 (size_t var) 51 | { 52 | return peek32 (system_vars + var); 53 | } 54 | 55 | // Flags operations. 56 | 57 | blassic::sysvar::Flags1Bit blassic::sysvar::getFlags1 () 58 | { 59 | return static_cast (system_vars [Flags1] ); 60 | } 61 | 62 | blassic::sysvar::Flags2Bit blassic::sysvar::getFlags2 () 63 | { 64 | return static_cast (system_vars [Flags2] ); 65 | } 66 | 67 | bool blassic::sysvar::hasFlags1 (Flags1Bit f) 68 | { 69 | //return (getFlags1 () & f) != Flags1Clean; 70 | return getFlags1 ().has (f); 71 | } 72 | 73 | bool blassic::sysvar::hasFlags2 (Flags2Bit f) 74 | { 75 | //return (getFlags2 () & f) != Flags2Clean; 76 | return getFlags2 ().has (f); 77 | } 78 | 79 | void blassic::sysvar::setFlags1 (Flags1Bit f) 80 | { 81 | BlChar * const pflag= system_vars + Flags1; 82 | *pflag|= f.get (); 83 | } 84 | 85 | void blassic::sysvar::setFlags2 (Flags2Bit f) 86 | { 87 | BlChar * const pflag= system_vars + Flags2; 88 | *pflag|= f.get (); 89 | } 90 | 91 | // Initialization 92 | 93 | void blassic::sysvar::init () 94 | { 95 | TRACEFUNC (tr, "blassic::sysvar::init"); 96 | #ifndef NDEBUG 97 | { 98 | std::ostringstream oss; 99 | oss << "System vars address: " << 100 | static_cast (system_vars); 101 | TRMESSAGE (tr, oss.str () ); 102 | } 103 | #endif 104 | 105 | set16 (GraphicsWidth, 0); 106 | set16 (GraphicsHeight, 0); 107 | set16 (NumArgs, 0); 108 | set16 (VersionMajor, version::Major); 109 | set16 (VersionMinor, version::Minor); 110 | set16 (VersionRelease, version::Release); 111 | set32 (AutoInit, 10); 112 | set32 (AutoInc, 10); 113 | set32 (CharGen, reinterpret_cast (& charset::data) ); 114 | set (ShellResult, 0); 115 | set (TypeOfVal, 0); // VAL simple, number only. 116 | set (TypeOfNextCheck, 0); // Strict next check 117 | set (TypeOfDimCheck, 0); // Need erase before dim already dimensioned 118 | set16 (MaxHistory, 100); 119 | setFlags1 (Flags1Clean); 120 | // Bit 0: LOCATE style Microsoft (row, col), 121 | // Bit 1: TAB style normal. 122 | // Bit 2: THEN omitted not accepted. 123 | // Bit 3: Without space before number in PRINT. 124 | // Bit 4: Without initial space in STR$. 125 | // Bit 5: Without convert LF to CR. 126 | // Bit 6: Do not show debug info. 127 | // Bit 7: Strict GOTO mode. 128 | 129 | #ifdef BLASSIC_USE_WINDOWS 130 | const BlChar defaultprinterline= 1; 131 | #else 132 | const BlChar defaultprinterline= 0; 133 | #endif 134 | set (PrinterLine, defaultprinterline); 135 | 136 | // Changed this, the processor stack overflows easily 137 | // in windows, at least in W98 with C++ Builder. 138 | //set32 (MaxFnLevel, 1000); // Seems a good limit. 139 | set32 (MaxFnLevel, 50); 140 | 141 | set16 (DebugLevel, 0); 142 | set16 (Zone, 8); 143 | set (GraphRotate, 0); 144 | setFlags2 (Flags2Clean); 145 | // Bit 0: GOTO and GOSUB listed as one word. 146 | // Bit 1: true is -1 147 | // Bit 2: logical ops are binary 148 | // Bit 3: blank lines as comments. 149 | set16 (TronChannel, 0); 150 | set (TronFlags, 0); 151 | } 152 | 153 | // Fin de sysvar.cpp 154 | -------------------------------------------------------------------------------- /element.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_ELEMENT_H 2 | #define INCLUDE_ELEMENT_H 3 | 4 | // element.h 5 | // Revision 1-jan-2005 6 | 7 | #include "blassic.h" 8 | 9 | #include 10 | 11 | class Element { 12 | public: 13 | Element (ProgramPos ppos) : 14 | ppos (ppos) 15 | { } 16 | void nextchunk () { ppos.nextchunk (); } 17 | void nextline () { ppos.nextline (); } 18 | ProgramPos getpos () const { return ppos; } 19 | private: 20 | ProgramPos ppos; 21 | }; 22 | 23 | class ForElement : public Element { 24 | public: 25 | ForElement (const std::string & nvar, ProgramPos pos) : 26 | Element (pos), 27 | varname (nvar) 28 | { } 29 | virtual ~ForElement () { } 30 | virtual bool next ()= 0; 31 | const std::string var () const 32 | { return varname; } 33 | bool isvar (const std::string & nvar) const 34 | { return varname == nvar; } 35 | private: 36 | ForElement (const ForElement &); // Forbidden 37 | ForElement & operator = (const ForElement &); // Forbidden 38 | const std::string varname; 39 | }; 40 | 41 | class ForElementNumber : public ForElement { 42 | public: 43 | ForElementNumber (const std::string & nvar, 44 | ProgramPos pos, 45 | BlNumber initial, BlNumber nmax, BlNumber nstep); 46 | protected: 47 | BlNumber * varaddr, max, step; 48 | }; 49 | 50 | class ForElementNumberInc : public ForElementNumber { 51 | public: 52 | ForElementNumberInc (const std::string & var, ProgramPos pos, 53 | BlNumber initial, BlNumber max, BlNumber step); 54 | bool next (); 55 | }; 56 | 57 | class ForElementNumberDec : public ForElementNumber { 58 | public: 59 | ForElementNumberDec (const std::string & var, ProgramPos pos, 60 | BlNumber initial, BlNumber max, BlNumber step); 61 | bool next (); 62 | }; 63 | 64 | class ForElementInteger : public ForElement { 65 | public: 66 | ForElementInteger (const std::string & nvar, 67 | ProgramPos pos, 68 | BlInteger initial, BlInteger nmax, BlInteger nstep); 69 | protected: 70 | BlInteger * varaddr, max, step; 71 | }; 72 | 73 | class ForElementIntegerInc : public ForElementInteger { 74 | public: 75 | ForElementIntegerInc (const std::string & var, ProgramPos pos, 76 | BlInteger initial, BlInteger max, BlInteger step); 77 | bool next (); 78 | }; 79 | 80 | class ForElementIntegerDec : public ForElementInteger { 81 | public: 82 | ForElementIntegerDec (const std::string & var, ProgramPos pos, 83 | BlInteger initial, BlInteger max, BlInteger step); 84 | bool next (); 85 | }; 86 | 87 | inline ForElementNumber * newForElementNumber (const std::string & var, 88 | ProgramPos pos, BlNumber initial, BlNumber max, BlNumber step) 89 | { 90 | if (step >= 0.0) 91 | return new ForElementNumberInc (var, pos, initial, max, step); 92 | else 93 | return new ForElementNumberDec (var, pos, initial, max, step); 94 | } 95 | 96 | inline ForElementInteger * newForElementInteger (const std::string & var, 97 | ProgramPos pos, BlInteger initial, BlInteger max, BlInteger step) 98 | { 99 | if (step >= 0) 100 | return new ForElementIntegerInc (var, pos, initial, max, step); 101 | else 102 | return new ForElementIntegerDec (var, pos, initial, max, step); 103 | } 104 | 105 | class RepeatElement : public Element { 106 | public: 107 | RepeatElement (ProgramPos pos) : 108 | Element (pos) 109 | { } 110 | }; 111 | 112 | class WhileElement : public Element { 113 | public: 114 | WhileElement (ProgramPos pos) : 115 | Element (pos) 116 | { } 117 | }; 118 | 119 | class LocalLevel { 120 | public: 121 | LocalLevel (); 122 | LocalLevel (const LocalLevel & ll); 123 | ~LocalLevel (); 124 | LocalLevel & operator= (const LocalLevel & ll); 125 | void addlocalvar (const std::string & name); 126 | void freelocalvars (); 127 | private: 128 | class Internal; 129 | Internal * pi; 130 | }; 131 | 132 | class GosubElement : public Element, public LocalLevel { 133 | public: 134 | GosubElement (ProgramPos pos, bool is_polled) : 135 | Element (pos), 136 | is_gosub (true), 137 | is_polled (is_polled) 138 | { } 139 | GosubElement (LocalLevel & ll) : 140 | Element (0), 141 | LocalLevel (ll), 142 | is_gosub (false), 143 | is_polled (false) 144 | { } 145 | bool isgosub () const { return is_gosub; } 146 | bool ispolled () const { return is_polled; } 147 | private: 148 | bool is_gosub; 149 | bool is_polled; 150 | }; 151 | 152 | 153 | #endif 154 | 155 | // End of element.h 156 | -------------------------------------------------------------------------------- /mbf.cpp: -------------------------------------------------------------------------------- 1 | // mbf.cpp 2 | // Revision 9-jul-2004 3 | 4 | #include "mbf.h" 5 | #include "error.h" 6 | 7 | #include 8 | 9 | // For debugging: 10 | #include 11 | #include 12 | 13 | double mbf::mbf_s (const std::string & s) 14 | { 15 | if (s.size () != 4) 16 | throw ErrFunctionCall; 17 | unsigned char b0= s [0], b1= s [1], b2= s [2], b3= s [3]; 18 | double n= (b2 & 0x7F) | 0x80; 19 | n= 256 * n + b1; 20 | n= 256 * n + b0; 21 | short e= static_cast (b3 - 128 - 24); 22 | if (e > 0) 23 | for ( ; e > 0; --e) 24 | n*= 2; 25 | else 26 | for ( ; e < 0; ++e) 27 | n/= 2; 28 | if (b2 & 0x80) 29 | n= -n; 30 | return n; 31 | } 32 | 33 | double mbf::mbf_d (const std::string & s) 34 | { 35 | if (s.size () != 8) 36 | throw ErrFunctionCall; 37 | unsigned char b0= s [0], b1= s [1], b2= s [2], b3= s [3], 38 | b4= s [4], b5= s [5], b6= s [6], b7= s [7]; 39 | double n= (b6 & 0x7F) | 0x80; 40 | n= 256 * n + b5; 41 | n= 256 * n + b4; 42 | n= 256 * n + b3; 43 | n= 256 * n + b2; 44 | n= 256 * n + b1; 45 | n= 256 * n + b0; 46 | short e= static_cast (b7 - 128 - 56); 47 | if (e > 0) 48 | for ( ; e > 0; --e) 49 | n*= 2; 50 | else 51 | for ( ; e < 0; ++e) 52 | n/= 2; 53 | if (b6 & 0x80) 54 | n= -n; 55 | return n; 56 | } 57 | 58 | namespace { 59 | 60 | double zero= 0.0; 61 | 62 | } // namespace 63 | 64 | std::string mbf::to_mbf_s (double v) 65 | { 66 | bool negative= v < 0; 67 | if (negative) 68 | v= -v; 69 | int e= static_cast (log (v) / log (2) ); 70 | v/= pow (2, e - 23); 71 | unsigned long l= static_cast (v); 72 | 73 | #if 0 74 | std::cerr << "e= " << std::dec << e << 75 | " l= " << std::hex << 76 | std::setw (8) << std::setfill ('0') << 77 | l << std::endl; 78 | #endif 79 | 80 | unsigned char b3= static_cast (e + 128 + 1); 81 | unsigned char b2= static_cast (l / (256 * 256) ); 82 | unsigned char b1= static_cast ((l / 256) % 256); 83 | unsigned char b0= static_cast (l % 256); 84 | b2&= 0x7F; 85 | if (negative) 86 | b2|= 0x80; 87 | #if 0 88 | std::cerr << std::setw (2) << int (b0) << int (b1) << 89 | int (b2) << int (b3) << std::endl; 90 | #endif 91 | 92 | return std::string (1, char (b0) ) + char (b1) + char (b2) + char (b3); 93 | } 94 | 95 | std::string mbf::to_mbf_d (double v) 96 | { 97 | bool negative= v < 0; 98 | if (negative) 99 | v= -v; 100 | int e= static_cast (log (v) / log (2) ); 101 | v/= pow (2, e - 55); 102 | //unsigned long l= static_cast (v); 103 | double l; 104 | modf (v, & l); 105 | 106 | #if 0 107 | std::cerr << "e= " << std::dec << e << 108 | " l= " << std::hex << 109 | std::setw (8) << std::setfill ('0') << 110 | l << std::endl; 111 | #endif 112 | 113 | unsigned char b7= static_cast (e + 128 + 1); 114 | 115 | #if 0 116 | unsigned char b6= l / (256.0 * 256 * 256 * 256 * 256 * 256); 117 | unsigned char b5= (l / (256.0 * 256 * 256 * 256 * 256) ) % 256.0; 118 | unsigned char b4= (l / (256.0 * 256 * 256 * 256) ) % 256.0; 119 | unsigned char b3= (l / (256UL * 256 * 256) ) % 256.0; 120 | unsigned char b2= (l / (256 * 256) ) % 256.0; 121 | unsigned char b1= (l / 256) % 256.0; 122 | unsigned char b0= l % 256.0; 123 | #else 124 | double ll; 125 | modf (l / 256, & ll); 126 | unsigned char b0= static_cast (l - 256 * ll); 127 | l= ll; 128 | modf (l / 256, & ll); 129 | unsigned char b1= static_cast (l - 256 * ll); 130 | l= ll; 131 | modf (l / 256, & ll); 132 | unsigned char b2= static_cast (l - 256 * ll); 133 | l= ll; 134 | modf (l / 256, & ll); 135 | unsigned char b3= static_cast (l - 256 * ll); 136 | l= ll; 137 | modf (l / 256, & ll); 138 | unsigned char b4= static_cast (l - 256 * ll); 139 | l= ll; 140 | modf (l / 256, & ll); 141 | unsigned char b5= static_cast (l - 256 * ll); 142 | l= ll; 143 | unsigned char b6= static_cast (l); 144 | #endif 145 | b6&= 0x7F; 146 | if (negative) 147 | b6|= 0x80; 148 | 149 | #if 0 150 | std::cerr << std::setw (2) << int (b0) << int (b1) << 151 | int (b2) << int (b3) << std::endl; 152 | #endif 153 | 154 | return std::string (1, char (b0) ) + char (b1) + char (b2) + 155 | char (b3) + char (b4) + char (b5) + char (b6) + char (b7); 156 | } 157 | 158 | // End of mbf.cpp 159 | -------------------------------------------------------------------------------- /key.cpp: -------------------------------------------------------------------------------- 1 | // key.cpp 2 | // Revision 9-jan-2005 3 | 4 | #include "key.h" 5 | #include "trace.h" 6 | #include "blassic.h" 7 | 8 | #include 9 | 10 | #include // For debug info only. 11 | 12 | //#ifdef _Windows 13 | #ifdef BLASSIC_USE_WINDOWS 14 | 15 | #include 16 | 17 | #elif defined BLASSIC_USE_X 18 | 19 | #include 20 | 21 | #endif 22 | 23 | const std::string 24 | strPAGEUP ("PAGEUP"), 25 | strPAGEDOWN ("PAGEDOWN"), 26 | strEND ("END"), 27 | strHOME ("HOME"), 28 | strLEFT ("LEFT"), 29 | strUP ("UP"), 30 | strRIGHT ("RIGHT"), 31 | strDOWN ("DOWN"), 32 | strINSERT ("INSERT"), 33 | strDELETE ("DELETE"), 34 | strF1 ("F1"), 35 | strF2 ("F2"), 36 | strF3 ("F3"), 37 | strF4 ("F4"), 38 | strF5 ("F5"), 39 | strF6 ("F6"), 40 | strF7 ("F7"), 41 | strF8 ("F8"), 42 | strF9 ("F9"), 43 | strF10 ("F10"), 44 | strF11 ("F11"), 45 | strF12 ("F12"), 46 | strENTER ("\n"), 47 | strCLICK ("CLICK"), 48 | strSCLICK ("SCLICK"), 49 | strRELEASE ("RELEASE"), 50 | strSRELEASE ("SRELEASE"); 51 | 52 | namespace { 53 | 54 | typedef std::map mapkey_t; 55 | 56 | mapkey_t mapkey; 57 | 58 | inline void assignmapkey (unsigned int code, const std::string & name) 59 | { 60 | #ifndef NDEBUG 61 | mapkey_t::iterator it; 62 | if ( (it= mapkey.find (code) ) != mapkey.end () ) 63 | { 64 | std::cerr << "Error: key " << name << 65 | " has equal code than " << it->second << 66 | std::endl; 67 | throw 1; 68 | } 69 | #endif 70 | mapkey [code]= name; 71 | } 72 | 73 | bool initmapkey () 74 | { 75 | TRACEFUNC (tr, "initmapkey"); 76 | 77 | //#ifdef _Windows 78 | #ifdef BLASSIC_USE_WINDOWS 79 | 80 | assignmapkey (VK_PRIOR, strPAGEUP); 81 | assignmapkey (VK_NEXT, strPAGEDOWN); 82 | assignmapkey (VK_END, strEND); 83 | assignmapkey (VK_HOME, strHOME); 84 | assignmapkey (VK_LEFT, strLEFT); 85 | assignmapkey (VK_UP, strUP); 86 | assignmapkey (VK_RIGHT, strRIGHT); 87 | assignmapkey (VK_DOWN, strDOWN); 88 | assignmapkey (VK_INSERT, strINSERT); 89 | assignmapkey (VK_DELETE, strDELETE); 90 | assignmapkey (VK_F1, strF1); 91 | assignmapkey (VK_F2, strF2); 92 | assignmapkey (VK_F3, strF3); 93 | assignmapkey (VK_F4, strF4); 94 | assignmapkey (VK_F5, strF5); 95 | assignmapkey (VK_F6, strF6); 96 | assignmapkey (VK_F7, strF7); 97 | assignmapkey (VK_F8, strF8); 98 | assignmapkey (VK_F9, strF9); 99 | assignmapkey (VK_F10, strF10); 100 | assignmapkey (VK_F11, strF11); 101 | assignmapkey (VK_F12, strF12); 102 | 103 | #elif defined BLASSIC_USE_X 104 | 105 | assignmapkey (XK_Prior, strPAGEUP); 106 | assignmapkey (XK_KP_Prior, strPAGEUP); 107 | assignmapkey (XK_Next, strPAGEDOWN); 108 | assignmapkey (XK_KP_Next, strPAGEDOWN); 109 | assignmapkey (XK_End, strEND); 110 | assignmapkey (XK_KP_End, strEND); 111 | assignmapkey (XK_Home, strHOME); 112 | assignmapkey (XK_KP_Home, strHOME); 113 | assignmapkey (XK_Left, strLEFT); 114 | assignmapkey (XK_KP_Left, strLEFT); 115 | assignmapkey (XK_Up, strUP); 116 | assignmapkey (XK_KP_Up, strUP); 117 | assignmapkey (XK_Right, strRIGHT); 118 | assignmapkey (XK_KP_Right, strRIGHT); 119 | assignmapkey (XK_Down, strDOWN); 120 | assignmapkey (XK_KP_Down, strDOWN); 121 | assignmapkey (XK_Insert, strINSERT); 122 | assignmapkey (XK_KP_Insert, strINSERT); 123 | assignmapkey (XK_Delete, strDELETE); 124 | assignmapkey (XK_KP_Delete, strDELETE); 125 | assignmapkey (XK_F1, strF1); 126 | assignmapkey (XK_F2, strF2); 127 | assignmapkey (XK_F3, strF3); 128 | assignmapkey (XK_F4, strF4); 129 | assignmapkey (XK_F5, strF5); 130 | assignmapkey (XK_F6, strF6); 131 | assignmapkey (XK_F7, strF7); 132 | assignmapkey (XK_F8, strF8); 133 | assignmapkey (XK_F9, strF9); 134 | assignmapkey (XK_F10, strF10); 135 | assignmapkey (XK_F11, strF11); 136 | assignmapkey (XK_F12, strF12); 137 | 138 | #endif 139 | 140 | return true; 141 | } 142 | 143 | const bool mapkeyinited= initmapkey (); 144 | 145 | } // namespace 146 | 147 | std::string string_from_key (unsigned int key) 148 | { 149 | mapkey_t::const_iterator it= mapkey.find (key); 150 | if (it != mapkey.end () ) 151 | return it->second; 152 | return std::string (); 153 | } 154 | 155 | // End of key.cpp 156 | -------------------------------------------------------------------------------- /graphics.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_GRAPHICS_H 2 | #define INCLUDE_BLASSIC_GRAPHICS_H 3 | 4 | // graphics.h 5 | // Revision 9-jan-2005 6 | 7 | #include "blassic.h" 8 | 9 | namespace graphics { 10 | 11 | struct Point { 12 | int x, y; 13 | Point (int xx, int yy) : x (xx), y (yy) { } 14 | Point (): x (0), y (0) { } 15 | }; 16 | 17 | void initialize (const char * progname); 18 | void uninitialize (); 19 | 20 | void origin (int x, int y); 21 | void limits (int minx, int maxx, int miny, int maxy); 22 | 23 | void ink (int inknum, int cpccolor); 24 | void ink (int inknum, int r, int g, int b); 25 | void clearink (); 26 | 27 | //void idle (); 28 | using blassic::idle; 29 | 30 | void cls (); 31 | void cls (BlChannel n); 32 | void setmode (int width, int height, bool inverty, 33 | int zoomx= 1, int zoomy= 1); 34 | void setmode (int mode); 35 | void setmode (const std::string & mode); 36 | bool ingraphicsmode (); 37 | 38 | void setcolor (int color); 39 | int getcolor (); 40 | void setcolor (BlChannel ch, int color); 41 | int getcolor (BlChannel ch); 42 | void setbackground (int color); 43 | int getbackground (); 44 | void setbackground (BlChannel ch, int color); 45 | int getbackground (BlChannel ch); 46 | 47 | void settransparent (int transpmode); 48 | void setdrawmode (int mode); 49 | 50 | void line (int x, int y); 51 | void liner (int x, int y); 52 | void drawarc (int x, int y, double g); 53 | 54 | void rectangle (Point org, Point dest); 55 | void rectanglefilled (Point org, Point dest); 56 | 57 | void zxplot (Point p); 58 | void zxunplot (Point p); 59 | 60 | void move (int x, int y); 61 | void mover (int x, int y); 62 | void plot (int x, int y); 63 | void plotr (int x, int y); 64 | void plot (std::vector & points); 65 | int test (int x, int y, bool relative); 66 | 67 | void circle (int x, int y, int radius); 68 | void arccircle (int x, int y, int radius, 69 | BlNumber arcbeg, BlNumber arcend); 70 | void ellipse (int x, int y, int rx, int ry); 71 | void arcellipse (int x, int y, int rx, int ry, 72 | BlNumber arcbeg, BlNumber arcend); 73 | 74 | void paint (int x, int y, int paintattr, int borderattr); 75 | 76 | void mask (int m); 77 | void maskdrawfirstpoint (bool f); 78 | void draw (const std::string & str); 79 | Point getlast (); 80 | 81 | std::string getkey (); 82 | std::string inkey (); 83 | bool pollin (); 84 | int keypressed (int keynum); 85 | 86 | void charout (char c); 87 | void stringout (const std::string & str); 88 | 89 | void charout (BlChannel ch, char c); 90 | void stringout (BlChannel ch, const std::string & str); 91 | std::string copychr (BlChannel ch, BlChar from, BlChar to); 92 | 93 | std::string screenchr (int x, int y); 94 | 95 | void definewindow (BlChannel n, int x1, int x2, int y1, int y2); 96 | void undefinewindow (BlChannel ch); 97 | 98 | size_t getlinewidth (); 99 | size_t getlinewidth (BlChannel ch); 100 | 101 | //void locate (int row, int col); 102 | void gotoxy (int x, int y); 103 | void tab (size_t n); 104 | void movecharforward (size_t n); 105 | void movecharback (size_t n); 106 | void movecharup (size_t n); 107 | void movechardown (size_t n); 108 | 109 | void gotoxy (BlChannel ch, int x, int y); 110 | void tab (BlChannel ch); 111 | void tab (BlChannel ch, size_t x); 112 | void movecharforward (BlChannel ch, size_t n); 113 | void movecharback (BlChannel ch, size_t n); 114 | void movecharup (BlChannel ch, size_t n); 115 | void movechardown (BlChannel ch, size_t n); 116 | 117 | void scroll (BlChannel ch, int n); 118 | 119 | void symbolafter (int symbol); 120 | void definesymbol (int symbol, const unsigned char (& byte) [8] ); 121 | void synchronize (bool mode); 122 | void synchronize (); 123 | void synchronize_suspend (); 124 | void synchronize_restart (); 125 | 126 | int xmouse (); 127 | int ymouse (); 128 | 129 | int xpos (); 130 | int xpos (BlChannel ch); 131 | int ypos (); 132 | int ypos (BlChannel ch); 133 | 134 | void tag (BlChannel ch); 135 | void tagoff (BlChannel ch); 136 | bool istagactive (BlChannel ch); 137 | 138 | void showcursor (); 139 | void hidecursor (); 140 | 141 | void showcursor (BlChannel ch); 142 | void hidecursor (BlChannel ch); 143 | 144 | void inverse (BlChannel ch, bool active); 145 | bool getinverse (BlChannel ch); 146 | void bright (BlChannel ch, bool active); 147 | bool getbright (BlChannel ch); 148 | 149 | void clean_input (); 150 | 151 | void ring (); 152 | 153 | void set_title (const std::string & title); 154 | void set_default_title (const std::string & title); 155 | 156 | void get_image (int x1, int y1, int x2, int y2, const std::string & name); 157 | void put_image (int x, int y, const std::string & name, int mode); 158 | void clear_images (); 159 | 160 | } // namespace graphics 161 | 162 | #endif 163 | 164 | // Fin de graphics.h 165 | -------------------------------------------------------------------------------- /dynamic.cpp: -------------------------------------------------------------------------------- 1 | // dynamic.cpp 2 | // Revision 1-jan-2005 3 | 4 | #include "dynamic.h" 5 | #include "error.h" 6 | #include "showerror.h" 7 | 8 | // For debugging. 9 | #include 10 | #include 11 | using std::cerr; 12 | using std::endl; 13 | 14 | 15 | #if (defined __unix__ || defined __linux__ || defined __NetBSD__) && \ 16 | ! defined __CYGWIN__ 17 | // Kylix defines only __linux__ 18 | 19 | 20 | #ifdef __hpux__ 21 | 22 | 23 | #include 24 | 25 | class DynamicHandle::Internal { 26 | shl_t handle; 27 | public: 28 | Internal (const std::string & name); 29 | ~Internal (); 30 | DynamicUsrFunc addr (const std::string & str); 31 | }; 32 | 33 | DynamicHandle::Internal::Internal (const std::string & name) 34 | { 35 | handle= shl_load (name.c_str (), BIND_DEFERRED, 0); 36 | if (handle == NULL) 37 | throw ErrNoDynamicLibrary; 38 | } 39 | 40 | DynamicHandle::Internal::~Internal () 41 | { 42 | // HP-UX seems to unload the library even if it was 43 | // opened several times, then we don't unload it. 44 | //shl_unload (handle); 45 | } 46 | 47 | DynamicUsrFunc DynamicHandle::Internal::addr (const std::string & str) 48 | { 49 | void * value; 50 | if (shl_findsym (& handle, str.c_str (), TYPE_UNDEFINED, 51 | & value) == 0) 52 | { 53 | //return reinterpret_cast (value); 54 | return (DynamicUsrFunc) (value); 55 | } 56 | else 57 | throw ErrNoDynamicSymbol; 58 | } 59 | 60 | #else 61 | // Unix no hp-ux 62 | 63 | 64 | #include 65 | 66 | class DynamicHandle::Internal { 67 | void * handle; 68 | public: 69 | Internal (const std::string & name); 70 | ~Internal (); 71 | DynamicUsrFunc addr (const std::string & str); 72 | }; 73 | 74 | DynamicHandle::Internal::Internal (const std::string & name) 75 | { 76 | handle= dlopen (name.c_str (), RTLD_LAZY); 77 | if (handle == NULL) 78 | { 79 | if (showdebuginfo () ) 80 | { 81 | cerr << "Error loading " << name << ": " << 82 | dlerror () << endl; 83 | } 84 | throw ErrNoDynamicLibrary; 85 | } 86 | } 87 | 88 | DynamicHandle::Internal::~Internal () 89 | { 90 | dlclose (handle); 91 | } 92 | 93 | DynamicUsrFunc DynamicHandle::Internal::addr (const std::string & str) 94 | { 95 | void * value; 96 | if ( (value= dlsym (handle, str.c_str () ) ) != NULL) 97 | { 98 | //return reinterpret_cast (value); 99 | return (DynamicUsrFunc) value; 100 | } 101 | else 102 | throw ErrNoDynamicSymbol; 103 | } 104 | 105 | #endif 106 | 107 | 108 | #elif defined BLASSIC_USE_WINDOWS 109 | 110 | 111 | #include 112 | #undef min 113 | #undef max 114 | 115 | namespace { 116 | 117 | void * GetAddress (HMODULE handle, const std::string & str) 118 | { 119 | FARPROC result= GetProcAddress (handle, str.c_str () ); 120 | if (result == NULL) 121 | { 122 | std::string str_ (1, '_'); 123 | str_+= str; 124 | result= GetProcAddress (handle, str_.c_str () ); 125 | } 126 | if (result == NULL) 127 | { 128 | showlasterror (); 129 | throw ErrNoDynamicSymbol; 130 | } 131 | return (void *) (result); 132 | } 133 | 134 | } // namespace 135 | 136 | class DynamicHandle::Internal { 137 | HMODULE handle; 138 | public: 139 | Internal (const std::string & name); 140 | ~Internal (); 141 | DynamicUsrFunc addr (const std::string & str); 142 | }; 143 | 144 | DynamicHandle::Internal::Internal (const std::string & name) 145 | { 146 | handle= LoadLibrary (name.c_str () ); 147 | if (handle == NULL) 148 | { 149 | showlasterror (); 150 | throw ErrNoDynamicLibrary; 151 | } 152 | } 153 | 154 | DynamicHandle::Internal::~Internal () 155 | { 156 | FreeLibrary (handle); 157 | } 158 | 159 | DynamicUsrFunc DynamicHandle::Internal::addr (const std::string & str) 160 | { 161 | return (DynamicUsrFunc) GetAddress (handle, str); 162 | } 163 | 164 | #else 165 | 166 | 167 | #warning Dynamic link unsupported 168 | 169 | class DynamicHandle::Internal { 170 | public: 171 | Internal (const std::string & name); 172 | ~Internal (); 173 | DynamicUsrFunc addr (const std::string & str); 174 | }; 175 | 176 | DynamicHandle::Internal::Internal (const std::string & name) 177 | { 178 | throw ErrDynamicUnsupported; 179 | } 180 | 181 | DynamicHandle::Internal::~Internal () 182 | { 183 | } 184 | 185 | DynamicUsrFunc DynamicHandle::Internal::addr (const std::string & str) 186 | { 187 | throw ErrDynamicUnsupported; 188 | } 189 | 190 | #endif 191 | 192 | 193 | DynamicHandle::DynamicHandle () : 194 | pin (0) 195 | { 196 | } 197 | 198 | DynamicHandle::DynamicHandle (const std::string & name) : 199 | pin (new Internal (name) ) 200 | { 201 | } 202 | 203 | void DynamicHandle::assign (const std::string & name) 204 | { 205 | // Create the new before destructing the old, thus leaving 206 | // intouched in case of exception. 207 | Internal * npin= new Internal (name); 208 | delete pin; 209 | pin= npin; 210 | } 211 | 212 | DynamicHandle::~DynamicHandle () 213 | { 214 | delete pin; 215 | } 216 | 217 | DynamicUsrFunc DynamicHandle::addr (const std::string & str) 218 | { 219 | return pin->addr (str); 220 | } 221 | 222 | // Fin de dymanic.cpp 223 | -------------------------------------------------------------------------------- /util.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_UTIL_H 2 | #define INCLUDE_UTIL_H 3 | 4 | // util.h 5 | // Revision 24-apr-2009 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | 14 | #ifdef __BORLANDC__ 15 | #pragma warn -8027 16 | #endif 17 | 18 | namespace util { 19 | 20 | inline std::string stringlset (const std::string & value, 21 | std::string::size_type l) 22 | { 23 | const std::string::size_type lvalue= value.size (); 24 | if (lvalue < l) 25 | return value + std::string (l - lvalue, ' '); 26 | else if (lvalue > l) 27 | return value.substr (0, l); 28 | else 29 | return value; 30 | } 31 | 32 | inline std::string stringrset (const std::string & value, 33 | std::string::size_type l) 34 | { 35 | const std::string::size_type lvalue= value.size (); 36 | if (lvalue < l) 37 | return std::string (l - lvalue, ' ') + value; 38 | else if (lvalue > l) 39 | return value.substr (0, l); 40 | else 41 | return value; 42 | } 43 | 44 | template 45 | DEST checked_cast (ORG org, EX ex) 46 | { 47 | DEST dest= static_cast (org); 48 | if (static_cast (dest) != org) 49 | throw ex; 50 | return dest; 51 | } 52 | 53 | template 54 | size_t dim_array (C (&) [N]) 55 | { return N; } 56 | 57 | template 58 | size_t dim_array (const C (&) [N]) 59 | { return N; } 60 | 61 | template 62 | class auto_buffer 63 | { 64 | public: 65 | auto_buffer (size_t ns) : 66 | p (new C [ns]), 67 | s (ns) 68 | { } 69 | auto_buffer () : p (0) { } 70 | ~auto_buffer () 71 | { delete [] p; } 72 | void release () { p= 0; } 73 | void alloc (size_t ns) 74 | { 75 | delete [] p; 76 | p= new C [ns]; 77 | s= ns; 78 | } 79 | operator C * () { return p; } 80 | typedef C * iterator; 81 | iterator begin () { return p; } 82 | iterator end () { return p + s; } 83 | // We define data for commodity, and better legibility 84 | // than begin where not used as iterator. 85 | C * data () { return p; } 86 | private: 87 | auto_buffer (const auto_buffer &); // Forbidden 88 | auto_buffer & operator = (const auto_buffer &); // Forbidden 89 | C * p; 90 | size_t s; 91 | }; 92 | 93 | template 94 | class auto_alloc 95 | { 96 | public: 97 | auto_alloc (size_t size) : 98 | p (static_cast (malloc (size * sizeof (C) ) ) ) 99 | { 100 | if (p == 0) 101 | throw std::bad_alloc (); 102 | } 103 | ~auto_alloc () 104 | { free (p); } 105 | void release () { p= 0; } 106 | operator C * () { return p; } 107 | C * data () { return p; } // Commodity when cast is needed 108 | private: 109 | auto_alloc (const auto_alloc &); // Forbidden 110 | auto_alloc & operator = (const auto_alloc &); // Forbidden 111 | C * p; 112 | }; 113 | 114 | // This template is intended for use as a pointer to a 115 | // private implementation that translates the constness of 116 | // the operations in the main class to the implementation. 117 | 118 | template 119 | class pimpl_ptr 120 | { 121 | public: 122 | pimpl_ptr (C * ptr) : 123 | p (ptr) 124 | { } 125 | ~pimpl_ptr () 126 | { 127 | delete p; 128 | } 129 | 130 | // Bypass the acces control 131 | C * get () const 132 | { return p; } 133 | 134 | // The dereference operator that preserves constness. 135 | C & operator * () 136 | { return * p; } 137 | const C & operator * () const 138 | { return * p; } 139 | C * operator -> () 140 | { return p; } 141 | const C * operator -> () const 142 | { 143 | return p; 144 | } 145 | private: 146 | pimpl_ptr (const pimpl_ptr &); // Forbidden 147 | pimpl_ptr & operator = (const pimpl_ptr &); // Forbidden 148 | C * const p; 149 | }; 150 | 151 | template 152 | std::string to_string (const C & c) 153 | { 154 | std::ostringstream oss; 155 | oss << c; 156 | return oss.str (); 157 | } 158 | 159 | // Functions used to avoid warnings about unused parameters. 160 | 161 | template 162 | inline void touch (const T & t) 163 | { 164 | (void) t; 165 | } 166 | template 167 | inline void touch (const T1 & t1, const T2 & t2) 168 | { 169 | (void) t1; (void) t2; 170 | } 171 | template 172 | inline void touch (const T1 & t1, const T2 & t2, const T3 & t3) 173 | { 174 | (void) t1; (void) t2; (void) t3; 175 | } 176 | template 177 | inline void touch (const T1 & t1, const T2 & t2, const T3 & t3, 178 | const T4 & t4) 179 | { 180 | (void) t1; (void) t2; (void) t3; 181 | (void) t4; 182 | } 183 | template 184 | inline void touch (const T1 & t1, const T2 & t2, const T3 & t3, 185 | const T4 & t4, const T5 & t5) 186 | { 187 | (void) t1; (void) t2; (void) t3; 188 | (void) t4; (void) t5; 189 | } 190 | template 191 | inline void touch (const T1 & t1, const T2 & t2, const T3 & t3, 192 | const T4 & t4, const T5 & t5, const T6 & t6) 193 | { 194 | (void) t1; (void) t2; (void) t3; 195 | (void) t4; (void) t5; (void) t6; 196 | } 197 | 198 | } // namespace 199 | 200 | #endif 201 | 202 | // End of util.h 203 | -------------------------------------------------------------------------------- /directory.cpp: -------------------------------------------------------------------------------- 1 | // directory.cpp 2 | // Revision 9-jan-2005 3 | 4 | #include "directory.h" 5 | 6 | #include "error.h" 7 | #include "showerror.h" 8 | 9 | #include "trace.h" 10 | 11 | #include 12 | #include 13 | 14 | // We use the unix style even on windows under cygwin. 15 | #if defined __unix__ || defined __linux__ || defined __NetBSD__ || \ 16 | defined __APPLE__ 17 | #define USE_UNIX 18 | #endif 19 | 20 | #ifdef USE_UNIX 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #else 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #ifdef __MINGW32__ 35 | #include 36 | #else 37 | using std::unlink; 38 | #endif 39 | 40 | #endif 41 | 42 | // ********************* Directory::Internal ************************* 43 | 44 | class Directory::Internal { 45 | public: 46 | Internal (); 47 | ~Internal (); 48 | std::string findfirst (const std::string & str); 49 | std::string findnext (); 50 | void closesearch (); 51 | private: 52 | Internal (const Internal &); // Forbidden 53 | Internal & operator = (const Internal &); // Forbidden 54 | 55 | bool finding; 56 | #ifdef USE_UNIX 57 | glob_t g; 58 | size_t n; 59 | #else 60 | WIN32_FIND_DATA fd; 61 | HANDLE h; 62 | #endif 63 | }; 64 | 65 | Directory::Internal::Internal () : 66 | finding (false) 67 | { 68 | } 69 | 70 | Directory::Internal::~Internal () 71 | { 72 | TRACEFUNC (tr, "Directory::Internal::~Internal"); 73 | 74 | if (finding) 75 | closesearch (); 76 | } 77 | 78 | std::string Directory::Internal:: findfirst (const std::string & str) 79 | { 80 | if (finding) 81 | closesearch (); 82 | finding= true; 83 | #ifdef USE_UNIX 84 | glob (str.c_str (), 0, NULL, & g); 85 | if (g.gl_pathc == 0) 86 | { 87 | closesearch (); 88 | return std::string (); 89 | } 90 | n= 1; 91 | return g.gl_pathv [0]; 92 | #else 93 | h= FindFirstFile (str.c_str (), & fd); 94 | if (h == INVALID_HANDLE_VALUE) 95 | { 96 | closesearch (); 97 | return std::string (); 98 | } 99 | return fd.cFileName; 100 | #endif 101 | } 102 | 103 | std::string Directory::Internal:: findnext () 104 | { 105 | if (! finding) 106 | return std::string (); 107 | #ifdef USE_UNIX 108 | if (n >= static_cast (g.gl_pathc) ) 109 | { 110 | closesearch (); 111 | return std::string (); 112 | } 113 | ++n; 114 | return g.gl_pathv [n - 1]; 115 | #else 116 | if (! FindNextFile (h, & fd) ) 117 | { 118 | closesearch (); 119 | return std::string (); 120 | } 121 | return fd.cFileName; 122 | #endif 123 | } 124 | 125 | void Directory::Internal::closesearch () 126 | { 127 | #ifdef USE_UNIX 128 | globfree (& g); 129 | #else 130 | if (h != INVALID_HANDLE_VALUE) 131 | FindClose (h); 132 | #endif 133 | finding= false; 134 | } 135 | 136 | // ********************* Directory ************************* 137 | 138 | Directory::Directory () : 139 | pin (new Internal) 140 | { 141 | } 142 | 143 | Directory::~Directory () 144 | { 145 | delete pin; 146 | } 147 | 148 | std::string Directory::findfirst (const std::string & str) 149 | { 150 | return pin->findfirst (str); 151 | } 152 | 153 | std::string Directory::findnext () 154 | { 155 | return pin->findnext (); 156 | } 157 | 158 | // ********************* Other functions ************************* 159 | 160 | void remove_file (const std::string & filename) 161 | { 162 | if (unlink (filename.c_str () ) != 0) 163 | { 164 | switch (errno) 165 | { 166 | case ENOENT: 167 | throw ErrFileNotFound; 168 | default: 169 | showlasterror (); 170 | throw ErrOperatingSystem; 171 | } 172 | } 173 | } 174 | 175 | void rename_file (const std::string & orig, const std::string & dest) 176 | { 177 | if (rename (orig.c_str (), dest.c_str () ) != 0) 178 | { 179 | switch (errno) 180 | { 181 | case ENOENT: 182 | throw ErrFileNotFound; 183 | default: 184 | showlasterror (); 185 | throw ErrRenameFile; 186 | } 187 | } 188 | } 189 | 190 | void change_dir (const std::string & dirname) 191 | { 192 | if (chdir (dirname.c_str () ) != 0) 193 | { 194 | showlasterror (); 195 | throw ErrOperatingSystem; 196 | } 197 | } 198 | 199 | void make_dir (const std::string & dirname) 200 | { 201 | #ifdef USE_UNIX 202 | int r= mkdir (dirname.c_str (), 0777); 203 | #else 204 | int r= mkdir (dirname.c_str () ); 205 | #endif 206 | if (r != 0) 207 | { 208 | showlasterror (); 209 | throw ErrOperatingSystem; 210 | } 211 | } 212 | 213 | void remove_dir (const std::string & dirname) 214 | { 215 | if (rmdir (dirname.c_str () ) != 0) 216 | { 217 | showlasterror (); 218 | throw ErrOperatingSystem; 219 | } 220 | } 221 | 222 | void sleep_milisec (unsigned long n) 223 | { 224 | TRACEFUNC (tr, "sleep_milisec"); 225 | 226 | #ifdef USE_UNIX 227 | 228 | if (n == 0) 229 | { 230 | usleep (0); 231 | } 232 | else 233 | { 234 | n*= 1000; 235 | unsigned int sec= n / 1000000; 236 | n%= 1000000; 237 | TRMESSAGE (tr, util::to_string (sec) + " sec, " + 238 | util::to_string (n) + " microsec"); 239 | if (sec > 0) 240 | sleep (sec); 241 | if (n > 0) 242 | usleep (n); 243 | } 244 | 245 | #else 246 | 247 | Sleep (static_cast (n) ); 248 | 249 | #endif 250 | } 251 | 252 | // End of directory.cpp 253 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am 2 | # Originally written by Pierre Sarrazin 3 | # Changes and additions by Julián Albo 4 | # Last revision 23-feb-2012 5 | 6 | noinst_PROGRAMS = gencharset 7 | bin_PROGRAMS = blassic 8 | 9 | 10 | # This tells Automake that charset.cpp must be generated before 11 | # anything else is compiled. 12 | 13 | # Changed, now use several charsets. 14 | #BUILT_SOURCES = charset.cpp 15 | # Testing other way. 16 | #BUILT_SOURCES = charset_default.cpp charset_cpc.cpp charset_spectrum.cpp charset_msx.cpp 17 | BUILT_SOURCES = gencharset$(EXEEXT) 18 | 19 | # Needed to generate charset cpp files: 20 | 21 | gencharset_SOURCES = gencharset.cpp 22 | 23 | gencharset_CXXFLAGS = $(CXXFLAGS_FOR_BUILD) 24 | 25 | gencharset_LDFLAGS = 26 | 27 | # This way the .exe extension is appended when compiling for windows 28 | # under linux, but it works anyway. 29 | gencharset$(EXEEXT): gencharset.cpp 30 | $(CXX_FOR_BUILD) $(gencharset_CXXFLAGS) $(gencharset_LDFLAGS) \ 31 | -o gencharset$(EXEEXT) \ 32 | gencharset.cpp 33 | 34 | # Character sets for graphics modes. 35 | 36 | #charset.cpp: $(srcdir)/charset.def gencharset 37 | # ./gencharset $(srcdir)/charset.def charset.cpp 38 | # test -f charset.cpp 39 | 40 | charset_default.cpp: $(srcdir)/default.def gencharset.cpp charset.h 41 | ./gencharset$(EXEEXT) $(srcdir)/default.def \ 42 | charset_default.cpp default 43 | test -f charset_default.cpp 44 | 45 | charset_cpc.cpp: $(srcdir)/cpc.def gencharset.cpp charset.h 46 | ./gencharset$(EXEEXT) $(srcdir)/cpc.def \ 47 | charset_cpc.cpp cpc 48 | test -f charset_cpc.cpp 49 | 50 | charset_spectrum.cpp: $(srcdir)/spectrum.def gencharset.cpp charset.h 51 | ./gencharset$(EXEEXT) $(srcdir)/spectrum.def \ 52 | charset_spectrum.cpp spectrum 53 | test -f charset_spectrum.cpp 54 | 55 | charset_msx.cpp: $(srcdir)/msx.def gencharset.cpp charset.h 56 | ./gencharset$(EXEEXT) $(srcdir)/msx.def \ 57 | charset_msx.cpp msx 58 | test -f charset_msx.cpp 59 | 60 | 61 | blassic_SOURCES = \ 62 | charset_default.cpp \ 63 | charset_cpc.cpp \ 64 | charset_spectrum.cpp \ 65 | charset_msx.cpp \ 66 | charset.h \ 67 | blassic.cpp \ 68 | blassic.h \ 69 | codeline.cpp \ 70 | codeline.h \ 71 | cursor.cpp \ 72 | cursor.h \ 73 | dim.cpp \ 74 | dim.h \ 75 | directory.cpp \ 76 | directory.h \ 77 | dynamic.cpp \ 78 | dynamic.h \ 79 | edit.cpp \ 80 | edit.h \ 81 | element.h \ 82 | element.cpp \ 83 | error.cpp \ 84 | error.h \ 85 | file.cpp \ 86 | file.h \ 87 | fileconsole.cpp \ 88 | filepopen.cpp \ 89 | fileprinter.cpp \ 90 | filesocket.cpp \ 91 | filewindow.cpp \ 92 | function.cpp \ 93 | function.h \ 94 | graphics.cpp \ 95 | graphics.h \ 96 | key.cpp \ 97 | key.h \ 98 | keyword.cpp \ 99 | keyword.h \ 100 | mbf.cpp \ 101 | mbf.h \ 102 | memory.cpp \ 103 | memory.h \ 104 | program.cpp \ 105 | program.h \ 106 | regexp.cpp \ 107 | regexp.h \ 108 | result.h \ 109 | runner.cpp \ 110 | runner.h \ 111 | runnerline.cpp \ 112 | runnerline.h \ 113 | runnerline_impl.cpp \ 114 | runnerline_impl.h \ 115 | runnerline_instructions.cpp \ 116 | runnerline_print.cpp \ 117 | showerror.cpp \ 118 | showerror.h \ 119 | socket.cpp \ 120 | socket.h \ 121 | sysvar.cpp \ 122 | sysvar.h \ 123 | token.cpp \ 124 | token.h \ 125 | trace.cpp \ 126 | trace.h \ 127 | using.cpp \ 128 | using.h \ 129 | util.h \ 130 | var.cpp \ 131 | var.h \ 132 | version.cpp 133 | 134 | blassic_CXXFLAGS = @SVGALIB_CFLAGS@ @BL_X_CFLAGS@ 135 | blassic_LDFLAGS = @BL_X_LIBS@ 136 | blassic_LDADD = @SVGALIB_LIBS@ @CYGWIN_FLAGS@ @BL_X_ADD@ 137 | 138 | 139 | # testdl: a tiny library to test blassic dynamic link. 140 | 141 | 142 | # Julian: modified this to allow cross-compiling. 143 | #testdl.so: testdl.o 144 | # gcc -shared -Wl,-soname,testdl.so -o testdl.so testdl.o 145 | #testdl.o: testdl.cpp 146 | # gcc -Wall -fPIC -c testdl.cpp 147 | 148 | #testdl_CXXFLAGS = \ 149 | # -W -Wall -Wwrite-strings -Wstrict-prototypes \ 150 | # -Wunused 151 | 152 | testdl.so: testdl.o 153 | $(CXX) -shared -Wl,-soname,testdl.so $(LDFLAGS) -o testdl.so testdl.o 154 | 155 | testdl.o: testdl.cpp 156 | $(CXX) -fPIC $(testdl_CXXFLAGS) -c testdl.cpp 157 | 158 | 159 | rpm: dist 160 | rpm -ta $(distdir).tar.gz 161 | 162 | EXTRA_DIST = \ 163 | bootstrap autogen.sh \ 164 | do_conf \ 165 | do_confnodeb \ 166 | do_confcross_arm \ 167 | do_confcross_mingw \ 168 | do_confhpux \ 169 | blassic.spec \ 170 | alphabet.blc automod.blc \ 171 | blassic.bpr \ 172 | testdl.bpr \ 173 | random.dat \ 174 | gencharset.cpp \ 175 | charset_default.cpp charset_cpc.cpp charset_spectrum.cpp charset_msx.cpp \ 176 | default.def cpc.def spectrum.def msx.def \ 177 | counter.sh \ 178 | testdl.cpp 179 | 180 | #CLEANFILES = testdl.so $(BUILT_SOURCES) 181 | CLEANFILES = testdl.so 182 | 183 | # When Automake needs to regenerate configure, the following options 184 | # will be passed to aclocal, as in the bootstrap script. 185 | ACLOCAL_AMFLAGS = -I . 186 | 187 | 188 | # Boilerplate: 189 | 190 | auxdir = @ac_aux_dir@ 191 | AUX_DIST = $(auxdir)/install-sh $(auxdir)/missing $(auxdir)/mkinstalldirs 192 | 193 | MAINTAINERCLEANFILES = \ 194 | Makefile.in \ 195 | aclocal.m4 \ 196 | configure \ 197 | sic/config-h.in \ 198 | sic/stamp-h.in \ 199 | $(AUX_DIST) \ 200 | depcomp \ 201 | config.guess \ 202 | config.log \ 203 | config.status \ 204 | config.sub \ 205 | install-sh \ 206 | missing \ 207 | mkinstalldirs 208 | 209 | -------------------------------------------------------------------------------- /gencharset.cpp: -------------------------------------------------------------------------------- 1 | // gencharset.cpp 2 | // Revision 31-jul-2004 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | // bitset in gcc 2.95 uses min whithout defining it. 10 | // Then we include something that does. 11 | #include 12 | #include 13 | 14 | using std::istream; 15 | using std::ostream; 16 | using std::cerr; 17 | using std::endl; 18 | using std::string; 19 | using std::runtime_error; 20 | 21 | void gencharset (const string & fin, const string & fout, 22 | const std::string & name); 23 | void readcharset (istream & in); 24 | void writecharset (ostream & out, const std::string & name); 25 | 26 | size_t linenumber= 0; 27 | 28 | int main (int argc, char * * argv) 29 | { 30 | try 31 | { 32 | string fin, fout, name; 33 | if (argc > 1) fin= argv [1]; 34 | if (argc > 2) fout= argv [2]; 35 | if (argc > 3) name= argv [3]; 36 | gencharset (fin, fout, name); 37 | } 38 | catch (std::exception & e) 39 | { 40 | cerr << e.what (); 41 | if (linenumber != 0) 42 | cerr << " in line " << linenumber; 43 | cerr << endl; 44 | } 45 | } 46 | 47 | typedef unsigned char chardata [8]; 48 | 49 | chardata default_data; 50 | bool default_defined= false; 51 | chardata data [256]; 52 | bool data_defined [256]= { false }; 53 | 54 | void gencharset (const string & fin, const string & fout, 55 | const std::string & name) 56 | { 57 | istream * pin; 58 | if (fin.empty () ) 59 | pin= & std::cin; 60 | else 61 | { 62 | std::ifstream * pinf= new std::ifstream (fin.c_str () ); 63 | if (! pinf->is_open () ) 64 | throw runtime_error ("File not found"); 65 | pin= pinf; 66 | } 67 | 68 | readcharset (* pin); 69 | 70 | if (! fin.empty () ) 71 | delete pin; 72 | 73 | linenumber= 0; 74 | 75 | ostream * pout; 76 | if (fout.empty () ) 77 | pout= & std::cout; 78 | else 79 | { 80 | std::ofstream * poutf= new std::ofstream (fout.c_str () ); 81 | if (! poutf->is_open () ) 82 | throw runtime_error ("Cannot create output file"); 83 | pout= poutf; 84 | } 85 | 86 | writecharset (* pout, name); 87 | 88 | if (! fout.empty () ) 89 | delete pout; 90 | } 91 | 92 | bool readline (istream & in, string & str) 93 | { 94 | do { 95 | std::getline (in, str); 96 | if (! in) 97 | return false; 98 | ++ linenumber; 99 | string::size_type l= str.size (); 100 | if (l > 0 && str [l - 1] == '\r') 101 | str= str.substr (0, l - 1); 102 | } while (str.empty () || str [0] == '#'); 103 | return true; 104 | } 105 | 106 | void readchar (istream & in, chardata & chd) 107 | { 108 | string str; 109 | bool invert= false; 110 | for (int i= 0; i < 8; ++i) 111 | { 112 | if (! readline (in, str) ) 113 | throw runtime_error ("Unexpected eof"); 114 | if (str == "INVERT") 115 | { 116 | invert= true; 117 | if (! readline (in, str) ) 118 | throw runtime_error ("Unexpected eof"); 119 | } 120 | std::bitset <8> b (str); 121 | unsigned long l= b.to_ulong (); 122 | if (invert) 123 | l= ~ l; 124 | chd [i]= static_cast (l); 125 | } 126 | } 127 | 128 | unsigned char getcharcode (const string & str) 129 | { 130 | if (str.size () == 1) 131 | return str [0]; 132 | std::istringstream iss (str); 133 | unsigned int u; 134 | iss >> u; 135 | if (! iss) 136 | throw runtime_error ("Syntax error"); 137 | char c; 138 | iss >> c; 139 | if (! iss.eof () ) 140 | throw runtime_error ("Syntax error"); 141 | if (u > 255) 142 | throw runtime_error ("Invalid char number"); 143 | return static_cast (u); 144 | } 145 | 146 | void readcharset (istream & in) 147 | { 148 | string str; 149 | while (readline (in, str) ) 150 | { 151 | //cerr << str << endl; 152 | if (str == "DEFAULT") 153 | { 154 | if (default_defined) 155 | throw runtime_error 156 | ("Default already defined"); 157 | //cerr << "Defining default" << endl; 158 | readchar (in, default_data); 159 | default_defined= true; 160 | } 161 | else 162 | { 163 | unsigned char ch= getcharcode (str); 164 | //cerr << "Defining char: "; 165 | //if (ch >= 32) cerr << ch; 166 | //else cerr << static_cast (ch); 167 | //cerr << endl; 168 | if (data_defined [ch] ) 169 | throw runtime_error ("Char already defined"); 170 | readchar (in, data [ch] ); 171 | data_defined [ch]= true; 172 | } 173 | } 174 | } 175 | 176 | void writecharset (ostream & out, const std::string & name) 177 | { 178 | if (name.empty () ) 179 | out << 180 | "// charset.cpp\n"; 181 | else 182 | out << 183 | "// charset_" << name << ".cpp\n"; 184 | 185 | out << 186 | "// Automatically generated, do not edit.\n" 187 | "\n" 188 | "#include \"charset.h\"\n" 189 | "\n" 190 | "const charset::chardataset charset::"; 191 | 192 | if (name.empty () ) 193 | out << "default"; 194 | else 195 | out << name; 196 | 197 | out << "_data= {\n" 198 | ; 199 | 200 | for (int i= 0; i < 256; ++i) 201 | { 202 | out << "\t// char " << i << "\n\t{ "; 203 | chardata * pdata; 204 | if (data_defined [i] ) pdata= & data [i]; 205 | else pdata= & default_data; 206 | for (int j= 0; j < 8; ++j) 207 | { 208 | out << static_cast ( (* pdata) [j] ); 209 | if (j < 7) out << ", "; 210 | } 211 | out << " },\n"; 212 | } 213 | out << 214 | 215 | "};\n" 216 | "\n" 217 | "//End of charset.cpp\n" 218 | ; 219 | } 220 | 221 | // End of gencharset.cpp 222 | -------------------------------------------------------------------------------- /sysvar.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_SYSVAR_H 2 | #define INCLUDE_BLASSIC_SYSVAR_H 3 | 4 | // sysvar.h 5 | // Revision 6-feb-2005 6 | 7 | #if defined __BORLANDC__ 8 | #pragma warn -8058 9 | #endif 10 | 11 | #include "blassic.h" 12 | 13 | 14 | namespace blassic { 15 | 16 | namespace sysvar { 17 | 18 | void init (); 19 | size_t address (); 20 | 21 | void set (size_t var, BlChar value); 22 | void set16 (size_t var, short value); 23 | void set32 (size_t var, BlInteger value); 24 | 25 | BlChar get (size_t var); 26 | unsigned short get16 (size_t var); 27 | unsigned long get32 (size_t var); 28 | 29 | const size_t 30 | GraphicsWidth= 0, 31 | GraphicsHeight= 2, 32 | NumArgs= 4, 33 | VersionMajor= 6, 34 | VersionMinor= 8, 35 | VersionRelease= 10, 36 | AutoInit= 12, 37 | AutoInc= 16, 38 | CharGen= 20, 39 | ShellResult= 24, 40 | TypeOfVal= 25, // 0: simple, 1: expression evluation, 41 | // else unimplemented. 42 | TypeOfNextCheck= 26, // 0: normal, else ZX-type 43 | TypeOfDimCheck= 27, // 0: cannot dim already dimensioned 44 | // 1: Silently redim 45 | MaxHistory= 28, // Max size of history buffer. 46 | Flags1= 30, // Bit 0: LOCATE style. 0 Microsoft, 1 Amstrad CPC. 47 | // Bit 1: TAB style: 0 normal, 1 Spectrum. 48 | // Bit 2: THEN omitted: 0 is not accepted, 1 accepted. 49 | // Bit 3: space before number in PRINT, 0 No, 1 Yes. 50 | // Bit 4: initial space in STR$, 0 No, 1 Yes. 51 | // Bit 5: convert LF to CR in GET and INKEY$ 52 | // Bit 6: Show debug info on certain errors. 53 | // Bit 7: Relaxed GOTO mode. 54 | PrinterLine= 31, // Type of printer line feed. 55 | // 0 LF only. 56 | // 1 CR + LF 57 | // 2 CR only. 58 | MaxFnLevel= 32, // Max level of FN calls. 59 | DebugLevel= 36, // Level for IF_DEBUG 60 | Zone= 38, // Size of zone for the , separator of PRINT. 61 | GraphRotate= 40, // Type of graphics rotation: 62 | // 0 no rotation. 63 | // 1 90 degrees. 64 | // Other: undefined 65 | Flags2= 41, // Bit 0: GO TO and GO SUB separated in listings. 66 | // Bit 1: if set true is positive. 67 | // Bit 2: if set logical ops are boolean. 68 | // Bit 3: if set blank lines in .bas text files 69 | // are converted to comments. 70 | // Bits 4-7: reserved. 71 | TronChannel= 42, // Last channel used for tron or tron line. 72 | TronFlags= 44, // Tron flags. 73 | // Bit 0: tron ot tron line is active. 74 | // Bit 1: tron line is active. 75 | // Bits 2-7: reserved. 76 | // 45: reserved 77 | EndSysVar= 46; 78 | 79 | // Flags masks. 80 | // Implemented as classes to improve type safety 81 | // and avoid silly mistakes. 82 | 83 | class Flags1Bit { 84 | public: 85 | explicit Flags1Bit (BlChar f) : 86 | f (f) 87 | { } 88 | BlChar get () const { return f; } 89 | bool has (const Flags1Bit f1bit) const; 90 | friend bool operator == (const Flags1Bit f1, const Flags1Bit f2); 91 | friend bool operator != (const Flags1Bit f1, const Flags1Bit f2); 92 | friend Flags1Bit operator | (const Flags1Bit f1, const Flags1Bit f2); 93 | friend Flags1Bit operator & (const Flags1Bit f1, const Flags1Bit f2); 94 | private: 95 | BlChar f; 96 | }; 97 | 98 | inline bool Flags1Bit::has (const Flags1Bit f1bit) const 99 | { 100 | return (f & f1bit.f); 101 | } 102 | 103 | inline bool operator == (const Flags1Bit f1, const Flags1Bit f2) 104 | { 105 | return f1.f == f2.f; 106 | } 107 | 108 | inline bool operator != (const Flags1Bit f1, const Flags1Bit f2) 109 | { 110 | return f1.f != f2.f; 111 | } 112 | 113 | inline Flags1Bit operator | (const Flags1Bit f1, const Flags1Bit f2) 114 | { 115 | return Flags1Bit (f1.f | f2.f); 116 | } 117 | 118 | inline Flags1Bit operator & (const Flags1Bit f1, const Flags1Bit f2) 119 | { 120 | return Flags1Bit (f1.f & f2.f); 121 | } 122 | 123 | class Flags2Bit { 124 | public: 125 | explicit Flags2Bit (BlChar f) : 126 | f (f) 127 | { } 128 | BlChar get () const { return f; } 129 | bool has (const Flags2Bit f2bit) const; 130 | friend bool operator == (const Flags2Bit f1, const Flags2Bit f2); 131 | friend bool operator != (const Flags2Bit f1, const Flags2Bit f2); 132 | friend Flags2Bit operator | (const Flags2Bit f1, const Flags2Bit f2); 133 | friend Flags2Bit operator & (const Flags2Bit f1, const Flags2Bit f2); 134 | private: 135 | BlChar f; 136 | }; 137 | 138 | inline bool Flags2Bit::has (const Flags2Bit f2bit) const 139 | { 140 | return (f & f2bit.f); 141 | } 142 | 143 | inline bool operator == (const Flags2Bit f1, const Flags2Bit f2) 144 | { 145 | return f1.f == f2.f; 146 | } 147 | 148 | inline bool operator != (const Flags2Bit f1, const Flags2Bit f2) 149 | { 150 | return f1.f != f2.f; 151 | } 152 | 153 | inline Flags2Bit operator | (const Flags2Bit f1, const Flags2Bit f2) 154 | { 155 | return Flags2Bit (f1.f | f2.f); 156 | } 157 | 158 | inline Flags2Bit operator & (const Flags2Bit f1, const Flags2Bit f2) 159 | { 160 | return Flags2Bit (f1.f & f2.f); 161 | } 162 | 163 | const Flags1Bit 164 | Flags1Clean (0), 165 | LocateStyle (1), 166 | TabStyle (2), 167 | ThenOmitted (4), 168 | SpaceBefore (8), 169 | SpaceStr_s (16), 170 | ConvertLFCR (32), 171 | ShowDebugInfo (64), 172 | RelaxedGoto (128), 173 | Flags1Full (255); 174 | 175 | const Flags2Bit 176 | Flags2Clean (0), 177 | SeparatedGoto (1), 178 | TruePositive (2), 179 | BoolMode (4), 180 | BlankComment (8), 181 | Flags2Full (255); 182 | 183 | Flags1Bit getFlags1 (); 184 | Flags2Bit getFlags2 (); 185 | 186 | bool hasFlags1 (Flags1Bit f); 187 | bool hasFlags2 (Flags2Bit f); 188 | 189 | void setFlags1 (Flags1Bit f); 190 | void setFlags2 (Flags2Bit f); 191 | 192 | } // namespace sysvar 193 | 194 | } // namespace blassic 195 | 196 | #endif 197 | 198 | // Fin de sysvar.h 199 | -------------------------------------------------------------------------------- /file.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_FILE_H 2 | #define INCLUDE_BLASSIC_FILE_H 3 | 4 | // file.h 5 | // Revision 7-feb-2005 6 | 7 | #ifdef __BORLANDC__ 8 | #pragma warn -8022 9 | #endif 10 | 11 | #include "blassic.h" 12 | 13 | #include "dim.h" 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | namespace blassic { 22 | 23 | namespace file { 24 | 25 | enum OpenMode { 26 | Input= 1, Output= 2, InOut= 3, 27 | Append= 6, Random= 8, Binary= 16, 28 | WithErr= 32 29 | }; 30 | 31 | class BlFile { 32 | public: 33 | struct field_element { 34 | size_t size; 35 | std::string name; 36 | Dimension dim; 37 | field_element (size_t n, 38 | const std::string & str, const Dimension & dim) 39 | : 40 | size (n), name (str), dim (dim) 41 | { } 42 | }; 43 | enum Align { AlignRight, AlignLeft }; 44 | 45 | BlFile (OpenMode nmode); 46 | virtual ~BlFile (); 47 | 48 | virtual void closein (); 49 | virtual void closeout (); 50 | 51 | virtual void reset (int x1, int x2, int y1, int y2); 52 | 53 | virtual bool isfile () const = 0; 54 | virtual bool istextwindow () const; 55 | virtual bool eof (); 56 | virtual size_t loc (); 57 | virtual void flush (); 58 | virtual size_t getwidth () const; 59 | virtual void movecharforward (); 60 | virtual void movecharforward (size_t n); 61 | virtual void movecharback (); 62 | virtual void movecharback (size_t n); 63 | virtual void movecharup (); 64 | virtual void movecharup (size_t n); 65 | virtual void movechardown (); 66 | virtual void movechardown (size_t n); 67 | virtual void showcursor (); 68 | virtual void hidecursor (); 69 | virtual std::string getkey (); 70 | virtual std::string inkey (); 71 | virtual void getline (std::string & str, bool endline= true); 72 | char delimiter () { return cDelimiter; } 73 | void delimiter (char delim) { cDelimiter= delim; } 74 | char quote () { return cQuote; } 75 | void quote (char qu) { cQuote= qu; } 76 | char escape () { return cEscape; } 77 | void escape (char esc) { cEscape= esc; } 78 | friend BlFile & operator << (BlFile & bf, const std::string & str); 79 | friend BlFile & operator << (BlFile & bf, char c); 80 | friend BlFile & operator << (BlFile & bf, BlNumber n); 81 | friend BlFile & operator << (BlFile & bf, BlInteger n); 82 | friend BlFile & operator << (BlFile & bf, BlLineNumber l); 83 | friend BlFile & operator << (BlFile & bf, unsigned short n); 84 | void putspaces (size_t n); 85 | virtual void tab (); 86 | virtual void tab (size_t n); 87 | virtual void endline (); 88 | virtual void put (size_t pos); 89 | virtual void get (size_t pos); 90 | virtual void field_clear (); 91 | virtual void field (const std::vector & elem); 92 | virtual void field_append (const std::vector & elem); 93 | virtual bool assign (const std::string & name, const Dimension & dim, 94 | const std::string & value, Align align); 95 | virtual bool assign_mid (const std::string & name, 96 | const Dimension & dim, 97 | const std::string & value, 98 | size_t inipos, std::string::size_type len); 99 | virtual std::string read (size_t n); 100 | virtual void gotoxy (int x, int y); 101 | virtual void setcolor (int color); 102 | virtual int getcolor (); 103 | virtual void setbackground (int color); 104 | virtual int getbackground (); 105 | virtual void cls (); 106 | virtual std::string copychr (BlChar from, BlChar to); 107 | virtual int pos (); 108 | virtual int vpos (); 109 | virtual void tag (); 110 | virtual void tagoff (); 111 | virtual bool istagactive (); 112 | virtual void inverse (bool active); 113 | virtual bool getinverse (); 114 | virtual void bright (bool active); 115 | virtual bool getbright (); 116 | virtual void setwidth (size_t w); 117 | virtual void setmargin (size_t m); 118 | virtual BlInteger lof (); 119 | virtual bool poll (); 120 | virtual void scroll (int nlines); 121 | private: 122 | virtual void outstring (const std::string & str); 123 | virtual void outchar (char c); 124 | 125 | BlFile (const BlFile &); // Forbidden 126 | void operator = (const BlFile &); // Forbidden. 127 | 128 | OpenMode mode; 129 | char cDelimiter, cQuote, cEscape; 130 | protected: 131 | OpenMode getmode () const { return mode; } 132 | }; 133 | 134 | // Create BlFile functions. 135 | 136 | BlFile * newBlFileConsole (); 137 | BlFile * newBlFileWindow (BlChannel ch); 138 | BlFile * newBlFileWindow (BlChannel ch, int x1, int x2, int y1, int y2); 139 | BlFile * newBlFileOutString (); 140 | BlFile * newBlFileOutput (std::ostream & os); 141 | BlFile * newBlFileRegular (const std::string & name, OpenMode mode); 142 | BlFile * newBlFileRandom (const std::string & name, size_t record_len); 143 | BlFile * newBlFilePopen (const std::string & name, OpenMode mode); 144 | BlFile * newBlFileSocket (const std::string & host, short port); 145 | BlFile * newBlFilePrinter (); 146 | 147 | class BlFileOut : public BlFile { 148 | public: 149 | BlFileOut (); 150 | BlFileOut (OpenMode mode); 151 | void flush (); 152 | protected: 153 | virtual std::ostream & ofs ()= 0; 154 | private: 155 | void outstring (const std::string & str); 156 | void outchar (char c); 157 | //void outnumber (BlNumber n); 158 | //void outinteger (BlInteger n); 159 | //void outlinenumber (BlLineNumber l); 160 | }; 161 | 162 | class BlFileOutString : public BlFileOut { 163 | public: 164 | BlFileOutString (); 165 | bool isfile () const { return false; } 166 | std::string str (); 167 | private: 168 | std::ostream & ofs (); 169 | std::ostringstream oss; 170 | }; 171 | 172 | } // namespace blassic 173 | 174 | } // namespace file 175 | 176 | #endif 177 | 178 | // Fin de file.h 179 | -------------------------------------------------------------------------------- /function.cpp: -------------------------------------------------------------------------------- 1 | // function.cpp 2 | // Revision 10-jul-2004 3 | 4 | #include "function.h" 5 | #include "error.h" 6 | 7 | #include 8 | #include 9 | 10 | class ParameterList::Internal { 11 | public: 12 | static Internal * getnew (); 13 | void addref (); 14 | void delref (); 15 | void push_back (const std::string & name); 16 | size_t size () const; 17 | //const std::string & get (size_t n) const; 18 | std::string get (size_t n) const; 19 | private: 20 | Internal (); 21 | Internal (const Internal &); // Forbidden 22 | ~Internal () { } 23 | void operator= (const Internal &); // Forbidden 24 | size_t counter; 25 | std::vector element; 26 | }; 27 | 28 | ParameterList::Internal::Internal () : 29 | counter (1) 30 | { 31 | } 32 | 33 | void ParameterList::Internal::addref () 34 | { 35 | ++counter; 36 | } 37 | 38 | void ParameterList::Internal::delref () 39 | { 40 | if (--counter == 0) 41 | delete this; 42 | } 43 | 44 | ParameterList::Internal * ParameterList::Internal::getnew () 45 | { 46 | return new Internal; 47 | } 48 | 49 | void ParameterList::Internal::push_back (const std::string & name) 50 | { 51 | element.push_back (name); 52 | } 53 | 54 | size_t ParameterList::Internal::size () const 55 | { 56 | return element.size (); 57 | } 58 | 59 | //const std::string & ParameterList::Internal::get (size_t n) const 60 | std::string ParameterList::Internal::get (size_t n) const 61 | { 62 | if (n >= element.size () ) 63 | throw ErrBlassicInternal; 64 | return element [n]; 65 | } 66 | 67 | ParameterList::ParameterList () : 68 | pin (Internal::getnew () ) 69 | { 70 | } 71 | 72 | ParameterList::ParameterList (const ParameterList & pl) : 73 | pin (pl.pin) 74 | { 75 | pin->addref (); 76 | } 77 | 78 | ParameterList::~ParameterList () 79 | { 80 | pin->delref (); 81 | } 82 | 83 | ParameterList & ParameterList::operator= (const ParameterList & pl) 84 | { 85 | pl.pin->addref (); 86 | pin->delref (); 87 | pin= pl.pin; 88 | return * this; 89 | } 90 | 91 | void ParameterList::push_back (const std::string & name) 92 | { 93 | pin->push_back (name); 94 | } 95 | 96 | size_t ParameterList::size () const 97 | { 98 | return pin->size (); 99 | } 100 | 101 | //const std::string & ParameterList::operator [] (size_t n) const 102 | std::string ParameterList::operator [] (size_t n) const 103 | { 104 | return pin->get (n); 105 | } 106 | 107 | class Function::Internal { 108 | public: 109 | void addref (); 110 | void delref (); 111 | static Internal * getnew 112 | (const std::string & strdef, const ParameterList & param) 113 | { 114 | return new Internal (strdef, param); 115 | } 116 | static Internal * getnew 117 | (ProgramPos posfn, const ParameterList & param) 118 | { 119 | return new Internal (posfn, param); 120 | } 121 | DefType getdeftype () const { return deftype; } 122 | CodeLine & getcode () { return code; } 123 | ProgramPos getpos () const { return pos; } 124 | const ParameterList & getparam () { return param; } 125 | protected: 126 | // Protected to avoid a warning on certain versions of gcc. 127 | Internal (const std::string & strdef, const ParameterList & param); 128 | ~Internal () { } 129 | private: 130 | Internal (ProgramPos posfn, const ParameterList & param); 131 | Internal (const Internal &); // Forbidden 132 | void operator = (const Internal &); // Forbidden 133 | size_t counter; 134 | DefType deftype; 135 | CodeLine code; 136 | ProgramPos pos; 137 | ParameterList param; 138 | }; 139 | 140 | Function::Internal::Internal 141 | (const std::string & strdef, const ParameterList & param) : 142 | counter (1), 143 | deftype (DefSingle), 144 | param (param) 145 | { 146 | code.scan (strdef); 147 | } 148 | 149 | Function::Internal::Internal 150 | (ProgramPos posfn, const ParameterList & param) : 151 | counter (1), 152 | deftype (DefMulti), 153 | pos (posfn), 154 | param (param) 155 | { 156 | } 157 | 158 | void Function::Internal::addref () 159 | { 160 | ++counter; 161 | } 162 | 163 | void Function::Internal::delref () 164 | { 165 | if (--counter == 0) 166 | delete this; 167 | } 168 | 169 | Function::Function (const std::string & strdef, const ParameterList & param) : 170 | pin (Internal::getnew (strdef, param) ) 171 | { 172 | } 173 | 174 | Function::Function (ProgramPos posfn, const ParameterList & param) : 175 | pin (Internal::getnew (posfn, param) ) 176 | { 177 | } 178 | 179 | Function::Function (const Function & f) : 180 | pin (f.pin) 181 | { 182 | pin->addref (); 183 | } 184 | 185 | Function::~Function () 186 | { 187 | pin->delref (); 188 | } 189 | 190 | Function & Function::operator= (const Function & f) 191 | { 192 | f.pin->addref (); 193 | pin->delref (); 194 | pin= f.pin; 195 | return * this; 196 | } 197 | 198 | Function::DefType Function::getdeftype () const 199 | { 200 | return pin->getdeftype (); 201 | } 202 | 203 | CodeLine & Function::getcode () 204 | { 205 | return pin->getcode (); 206 | } 207 | 208 | ProgramPos Function::getpos () const 209 | { 210 | return pin->getpos (); 211 | } 212 | 213 | const ParameterList & Function::getparam () 214 | { 215 | return pin->getparam (); 216 | } 217 | 218 | namespace { 219 | 220 | typedef std::map mapfunction_t; 221 | mapfunction_t mapfunction; 222 | 223 | } // namespace 224 | 225 | void Function::clear () 226 | { 227 | mapfunction.clear (); 228 | } 229 | 230 | void Function::insert (const std::string & name) 231 | { 232 | mapfunction_t::iterator it= 233 | mapfunction.find (name); 234 | if (it != mapfunction.end () ) 235 | it->second= * this; 236 | else 237 | mapfunction.insert (std::make_pair (name, * this) ); 238 | } 239 | 240 | Function & Function::get (const std::string & name) 241 | { 242 | mapfunction_t::iterator it= 243 | mapfunction.find (name); 244 | if (it != mapfunction.end () ) 245 | return it->second; 246 | throw ErrFunctionNoDefined; 247 | } 248 | 249 | // Fin de function.cpp 250 | -------------------------------------------------------------------------------- /blassic.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_H 2 | #define INCLUDE_BLASSIC_H 3 | 4 | // blassic.h 5 | // Revision 6-feb-2005 6 | 7 | // Now do not use hash_map at all. 8 | //#if ! defined __BORLANDC__ && __GNUC__ < 3 9 | //#if defined __GNUC__ 10 | //#define USE_HASH_MAP 11 | //#endif 12 | 13 | 14 | #if defined _Windows || defined __CYGWIN__ || defined __MINGW32__ 15 | 16 | 17 | #define BLASSIC_USE_WINDOWS 18 | 19 | #ifndef __MT__ 20 | #define __MT__ 21 | #endif 22 | 23 | 24 | #else 25 | 26 | 27 | // This is controlled with the configure option --disable-graphics 28 | #ifndef BLASSIC_CONFIG_NO_GRAPHICS 29 | 30 | #define BLASSIC_USE_X 31 | 32 | #endif 33 | 34 | 35 | #ifdef __linux__ 36 | 37 | // Uncomment next #define if you want to use the svgalib option 38 | // or tell it to configure. 39 | // Support for svgalib is currently outdated. 40 | //#define BLASSIC_USE_SVGALIB 41 | 42 | #endif 43 | 44 | #endif 45 | 46 | // Borland define _M_IX86, gcc define __i386__ 47 | #if defined (_M_IX86) || defined (__i386__) 48 | 49 | #define BLASSIC_INTEL 50 | 51 | // In other processor used the endianess is different and / or 52 | // there are restrictions of alignment. 53 | 54 | #endif 55 | 56 | 57 | #ifdef __BORLANDC__ 58 | #pragma warn -8027 59 | #endif 60 | 61 | 62 | #ifdef HAVE_CSTDLIB 63 | #include 64 | #else 65 | #include 66 | #endif 67 | 68 | #include 69 | #include 70 | #include 71 | 72 | // Now defined here instead of in var.h to reduce dependencies. 73 | 74 | enum VarType { VarUndef, VarNumber, VarInteger, 75 | VarString, VarStringSlice }; 76 | 77 | inline bool is_numeric_type (VarType v) 78 | { return v == VarNumber || v == VarInteger; } 79 | 80 | inline bool is_string_type (VarType v) 81 | { return v == VarString || v == VarStringSlice; } 82 | 83 | 84 | typedef unsigned char BlChar; 85 | typedef unsigned short BlCode; 86 | typedef double BlNumber; 87 | 88 | #if ULONG_MAX == 4294967295UL 89 | 90 | typedef long BlInt32; 91 | const BlInt32 BlInt32Max= LONG_MAX; 92 | const BlInt32 BlInt32Min= LONG_MIN; 93 | 94 | typedef unsigned long BlUint32; 95 | const BlUint32 BlUint32Max= ULONG_MAX; 96 | 97 | #elif UINT_MAX == 4294967295UL 98 | 99 | typedef int BlInt32; 100 | const BlInt32 BlInt32Max= INT_MAX; 101 | const BlInt32 BlInt32Min= INT_MIN; 102 | 103 | typedef unsigned int BlUint32; 104 | const BlUint32 BlUint32Max= UINT_MAX; 105 | 106 | #elif USHRT_MAX == 4294967295UL 107 | 108 | typedef short BlInt32; 109 | const BlInt32 BlInt32Max= SHRT_MAX; 110 | const BlInt32 BlInt32Min= SHRT_MIN; 111 | 112 | typedef unsigned short BlUint32; 113 | const BlUint32 BlUint32Max= USHRT_MAX; 114 | 115 | #else 116 | 117 | #error Unsupported platform 118 | 119 | #endif 120 | 121 | typedef BlInt32 BlInteger; 122 | typedef BlUint32 BlLineNumber; 123 | typedef BlUint32 BlLineLength; 124 | 125 | const BlInteger BlIntegerMax= BlInt32Max; 126 | const BlInteger BlIntegerMin= BlInt32Min; 127 | 128 | // We limit the max line number as if it were signed. 129 | const BlLineNumber BlMaxLineNumber= BlIntegerMax; 130 | 131 | // Special line number values. 132 | 133 | const BlLineNumber LineEndProgram= BlUint32Max; 134 | const BlLineNumber LineBeginProgram= BlUint32Max - 1; 135 | const BlLineNumber LineDirectCommand= BlUint32Max - 2; 136 | const BlLineNumber LineNoDelete= BlUint32Max - 3; 137 | 138 | typedef unsigned short BlChunk; 139 | typedef unsigned short BlErrNo; 140 | typedef unsigned short BlChannel; 141 | 142 | const BlChannel DefaultChannel= 0; 143 | const BlChannel PrinterChannel= 65535; 144 | 145 | class ProgramPos { 146 | public: 147 | ProgramPos () : 148 | num (LineEndProgram), chunk (0) 149 | { } 150 | ProgramPos (BlLineNumber num) : 151 | num (num), chunk (0) 152 | { } 153 | ProgramPos (BlLineNumber num, BlChunk chunk) : 154 | num (num), chunk (chunk) 155 | { } 156 | void operator= (BlLineNumber num) 157 | { 158 | this->num= num; 159 | chunk= 0; 160 | } 161 | void nextchunk () { ++chunk; } 162 | void nextline () { ++num; chunk= 0; } 163 | operator bool () { return num != 0 || chunk != 0; } 164 | BlLineNumber getnum () const { return num; } 165 | BlChunk getchunk () const { return chunk; } 166 | void setchunk (BlChunk n) { chunk= n; } 167 | private: 168 | BlLineNumber num; 169 | BlChunk chunk; 170 | }; 171 | 172 | // Global variables: 173 | 174 | //extern BlLineNumber blnAuto, blnAutoInc; 175 | 176 | extern bool fInterrupted; 177 | 178 | extern const std::string strPrompt; 179 | 180 | // version.cpp 181 | namespace version { 182 | 183 | extern const unsigned short Major, Minor, Release; 184 | 185 | } // namespace version 186 | 187 | class Exit { 188 | public: 189 | Exit (int ncode= 0); 190 | int code () const; 191 | private: 192 | int exitcode; 193 | }; 194 | 195 | std::string getprogramarg (size_t n); 196 | void setprogramargs (const std::vector & nargs); 197 | 198 | inline BlInteger peek16 (const BlChar * p) 199 | { 200 | #ifdef BLASSIC_INTEL 201 | return * reinterpret_cast (p); 202 | #else 203 | return p [0] | (static_cast (p [1]) << 8); 204 | #endif 205 | } 206 | 207 | inline void poke16 (BlChar * p, short n) 208 | { 209 | #ifdef BLASSIC_INTEL 210 | * reinterpret_cast (p)= n; 211 | #else 212 | p [0]= BlChar (n & 0xFF); 213 | p [1]= BlChar ( (n >> 8) & 0xFF); 214 | #endif 215 | } 216 | 217 | inline BlInteger peek32 (const BlChar * p) 218 | { 219 | #ifdef BLASSIC_INTEL 220 | return * reinterpret_cast (p); 221 | #else 222 | return p [0] | 223 | (BlInteger (p [1]) << 8) | 224 | (BlInteger (p [2]) << 16) | 225 | (BlInteger (p [3]) << 24); 226 | #endif 227 | } 228 | 229 | inline void poke32 (BlChar * p, BlUint32 n) 230 | { 231 | #ifdef BLASSIC_INTEL 232 | * reinterpret_cast (p)= n; 233 | #else 234 | p [0]= BlChar (n & 0xFF); 235 | p [1]= BlChar ( (n >> 8) & 0xFF); 236 | p [2]= BlChar ( (n >> 16) & 0xFF); 237 | p [3]= BlChar (n >> 24); 238 | #endif 239 | } 240 | 241 | inline void poke32 (BlChar * p, BlInteger n) 242 | { 243 | poke32 (p, static_cast (n) ); 244 | } 245 | 246 | namespace blassic { 247 | 248 | void idle (); // Implemented in graphics.cpp 249 | 250 | } // namespace blassic 251 | 252 | #endif 253 | 254 | // Fin de blassic.h 255 | -------------------------------------------------------------------------------- /token.cpp: -------------------------------------------------------------------------------- 1 | // token.cpp 2 | // Revision 25-jul-2004 3 | 4 | #include "token.h" 5 | #include 6 | #include 7 | 8 | using std::isalpha; 9 | using std::isdigit; 10 | using std::isxdigit; 11 | using std::isspace; 12 | 13 | Tokenizer::Tokenizer (const std::string & source) : 14 | str (source), pos (0), limit (source.size () ) 15 | { 16 | } 17 | 18 | unsigned char Tokenizer::peek () 19 | { 20 | if (pos < limit) 21 | return str [pos]; 22 | else 23 | return '\0'; 24 | } 25 | 26 | unsigned char Tokenizer::peeknospace () 27 | { 28 | unsigned char c= '\0'; 29 | std::string::size_type p= pos; 30 | while (p < limit && (c= str [p] ) == ' ') 31 | ++p; 32 | if (p < limit) 33 | return c; 34 | else 35 | return '\0'; 36 | } 37 | 38 | unsigned char Tokenizer::nextchar () 39 | { 40 | if (pos < limit) 41 | return str [pos++]; 42 | else 43 | return '\0'; 44 | } 45 | 46 | unsigned char Tokenizer::nextcharnospace () 47 | { 48 | unsigned char c= '\0'; 49 | while (pos < limit && (c= str [pos] ) == ' ') 50 | ++pos; 51 | if (pos < limit) 52 | { 53 | ++pos; 54 | return c; 55 | } 56 | else 57 | return '\0'; 58 | } 59 | 60 | void Tokenizer::ungetchar () 61 | { 62 | if (pos > 0) 63 | --pos; 64 | } 65 | 66 | //namespace { 67 | 68 | inline bool isident (char c) 69 | { 70 | return isalpha (c) || isdigit (c) || c == '_'; 71 | } 72 | 73 | //} 74 | 75 | Tokenizer::Token Tokenizer::get () 76 | { 77 | unsigned char c= nextchar (); 78 | if (c == '\0') 79 | return Token (EndLine); 80 | 81 | std::string str; 82 | if (isspace (c) ) 83 | { 84 | do { 85 | str+= c; 86 | } while (isspace (c= nextchar () ) ); 87 | if (c != '\0') 88 | ungetchar (); 89 | return Token (Blank, str); 90 | } 91 | 92 | switch (c) 93 | { 94 | case '"': 95 | //str+= c; 96 | while ( (c= nextchar () ) != '\0') 97 | { 98 | if (c == '"') 99 | { 100 | c= peek (); 101 | if (c != '"') 102 | break; 103 | nextchar (); 104 | } 105 | str+= c; 106 | } 107 | return Token (Literal, str); 108 | case '&': 109 | // Hex, octal or binary number 110 | str= '&'; 111 | c= nextchar (); 112 | if (c == 'x' || c == 'X') // Binary 113 | { 114 | str+= c; 115 | while ( (c= nextchar () ) == '0' || c == '1') 116 | str+= c; 117 | if (c != 0) 118 | ungetchar (); 119 | } 120 | else if (c == 'o' || c == 'O') // Octal 121 | { 122 | str+= c; 123 | while ( (c= nextchar () ) >= '0' && c <= '7') 124 | str+= c; 125 | if (c != 0) 126 | ungetchar (); 127 | } 128 | else // Hexadecimal 129 | { 130 | if (c == 'h' || c == 'H') 131 | { 132 | str+= c; 133 | c= nextchar (); 134 | } 135 | while (isxdigit (c) ) 136 | { 137 | str+= c; 138 | c= nextchar (); 139 | } 140 | if (c != 0) 141 | ungetchar (); 142 | } 143 | return Token (Plain, str); 144 | case '=': 145 | { 146 | str= c; 147 | c= peeknospace (); 148 | if (c == '>' || c == '<') 149 | { 150 | str+= c; 151 | (void) nextcharnospace (); 152 | } 153 | } 154 | return Token (Plain, str); 155 | case '<': 156 | str= c; 157 | c= peeknospace (); 158 | if (c == '=' || c == '>') 159 | { 160 | str+= c; 161 | (void) nextcharnospace (); 162 | } 163 | return Token (Plain, str); 164 | case '>': 165 | str= c; 166 | c= peeknospace (); 167 | if (c == '=' || c == '<') 168 | { 169 | str+= c; 170 | (void) nextcharnospace (); 171 | } 172 | return Token (Plain, str); 173 | default: 174 | ; // Later. 175 | } 176 | 177 | if (isalpha (c) ) 178 | { 179 | do 180 | { 181 | str+= c; 182 | } while ( isident (c= nextchar () ) ); 183 | if (c == '$') 184 | str+= c; 185 | else 186 | if (c != '\0') 187 | ungetchar (); 188 | return Token (Plain, str); 189 | } 190 | 191 | if (isdigit (c) || c == '.') 192 | { 193 | bool nofloat= true; 194 | while (isdigit (c) ) 195 | { 196 | str+= c; 197 | c= nextchar (); 198 | } 199 | if (c == '.') 200 | { 201 | str+= '.'; 202 | nofloat= false; 203 | while ( isdigit (c= nextchar () ) ) 204 | str+= c; 205 | } 206 | if (c == 'e' || c == 'E') 207 | { 208 | str+= c; 209 | nofloat= false; 210 | c= nextchar (); 211 | if (! isdigit (c) && c != '+' && c != '-') 212 | { 213 | // Data such as 1E 214 | while (isident (c) ) 215 | { 216 | str+= c; 217 | c= nextchar (); 218 | } 219 | if (c != 0) 220 | ungetchar (); 221 | return Token (Plain, str); 222 | } 223 | if (c == '+' || c == '-') 224 | { 225 | str+= c; 226 | c= nextchar (); 227 | } 228 | while (isdigit (c) ) 229 | { 230 | str+= c; 231 | c= nextchar (); 232 | } 233 | } 234 | if (c != 0) 235 | { 236 | if (isident (c) ) 237 | { 238 | do { 239 | str+= c; 240 | c= nextchar (); 241 | } while (isident (c) ); 242 | if (c != 0) 243 | ungetchar (); 244 | return Token (Plain, str); 245 | } 246 | ungetchar (); 247 | } 248 | if (nofloat) 249 | { 250 | #if 0 251 | std::istringstream iss (str); 252 | BlInteger n; 253 | iss >> n; 254 | if (iss) 255 | { 256 | iss.get (); 257 | //if (! iss) 258 | if (iss.eof () ) 259 | return Token (n); 260 | } 261 | #else 262 | BlInteger n= 0; 263 | std::string::size_type i; 264 | const std::string::size_type l= str.size (); 265 | for (i= 0; i < l; ++i) 266 | { 267 | BlInteger digit= str [i] - '0'; 268 | if (n > (BlIntegerMax / 10) ) 269 | break; 270 | n*= 10; 271 | if (n > BlIntegerMax - digit) 272 | break; 273 | n+= digit; 274 | } 275 | if (i == l) 276 | return Token (n); 277 | #endif 278 | } 279 | return Token (Plain, str); 280 | } 281 | 282 | // If nothing else: 283 | str= c; 284 | return Token (Plain, str); 285 | } 286 | 287 | std::string Tokenizer::getrest () 288 | { 289 | std::string r; 290 | char c; 291 | while ( (c= nextchar () ) != 0) 292 | { 293 | if (c == '"') 294 | { 295 | r+= c; 296 | while ( (c= nextchar () ) != '\0') 297 | { 298 | if (c == '"') 299 | { 300 | c= peek (); 301 | if (c != '"') 302 | break; 303 | nextchar (); 304 | } 305 | r+= c; 306 | } 307 | r+= '\0'; 308 | } 309 | else 310 | r+= c; 311 | } 312 | return r; 313 | } 314 | 315 | // Fin de token.cpp 316 | -------------------------------------------------------------------------------- /error.cpp: -------------------------------------------------------------------------------- 1 | // error.cpp 2 | // Revision 7-feb-2005 3 | 4 | #include "error.h" 5 | #include "sysvar.h" 6 | #include "util.h" 7 | 8 | #include 9 | #include 10 | 11 | namespace sysvar= blassic::sysvar; 12 | 13 | 14 | namespace { 15 | 16 | struct errcode { 17 | const BlErrNo err; 18 | const char * const str; 19 | errcode (BlErrNo nerr, const char * nstr) : 20 | err (nerr), 21 | str (nstr) 22 | { } 23 | }; 24 | 25 | // Can't declare const or Borland can't expand find_if. Why? 26 | errcode table []= { 27 | errcode (ErrNoError, "No error"), 28 | errcode (ErrSyntax, "Syntax horror"), 29 | errcode (ErrMismatch, "Type mismatch"), 30 | errcode (ErrGosubWithoutReturn, "GOSUB without RETURN"), 31 | errcode (ErrReturnWithoutGosub, "RETURN without GOSUB"), 32 | errcode (ErrNextWithoutFor, "NEXT without FOR"), 33 | errcode (ErrNotImplemented, "Not implemented"), 34 | errcode (ErrDivZero, "Division by zero"), 35 | errcode (ErrDataExhausted, "Data exhausted"), 36 | errcode (ErrInvalidCommand, "Invalid command"), 37 | errcode (ErrPolite, "Programmer is too polite"), 38 | errcode (ErrBadSubscript, "Bad Subscript"), 39 | errcode (ErrOutMemory, "Out of memory"), 40 | errcode (ErrAlreadyDim, "Array already dimensioned"), 41 | errcode (ErrNoContinue, "Cannot CONTinue"), 42 | errcode (ErrFileNumber, "Bad file number"), 43 | errcode (ErrFileMode, "Bad file mode"), 44 | errcode (ErrFileAlreadyOpen, "File already open"), 45 | errcode (ErrFileRead, "Error reading file"), 46 | errcode (ErrFileWrite, "Error writing file"), 47 | errcode (ErrUntilWithoutRepeat, "UNTIL without REPEAT"), 48 | errcode (ErrWendWithoutWhile, "WEND without WHILE"), 49 | errcode (ErrWhileWithoutWend, "WHILE without WEND"), 50 | errcode (ErrBlassicInternal, "Internal Blassic error"), 51 | errcode (ErrNoDynamicLibrary, "Dynamic library not found"), 52 | errcode (ErrNoDynamicSymbol, "Symbol not found in dynamic library"), 53 | errcode (ErrCannotResume, "Cannot RESUME"), 54 | errcode (ErrNoLabel, "Label does not exist"), 55 | errcode (ErrMisplacedLocal, "LOCAL out of subroutine"), 56 | errcode (ErrFieldOverflow, "FIELD overflow"), 57 | errcode (ErrFileNotFound, "File not found"), 58 | errcode (ErrLineExhausted, "Line numbers exhausted"), 59 | errcode (ErrFunctionNoDefined, "User function undefined"), 60 | errcode (ErrIncompleteDef, "User function incomplete"), 61 | errcode (ErrInvalidDirect, "Invalid direct command"), 62 | errcode (ErrBadRecord, "Bad record number"), 63 | errcode (ErrFunctionCall, "Illegal function call"), 64 | errcode (ErrSocket, "Socket error"), 65 | errcode (ErrRenameFile, "Rename file error"), 66 | errcode (ErrOperatingSystem, "Operating system error"), 67 | errcode (ErrPastEof, "Input past EOF"), 68 | errcode (ErrNoGraphics, "Graphics mode required"), 69 | errcode (ErrImproperArgument, "Improper argument"), 70 | errcode (ErrDomain, "Domain error"), 71 | errcode (ErrRange, "Result out of range"), 72 | errcode (ErrLineNotExist, "Line does not exist"), 73 | errcode (ErrFnRecursion, "FN recursion too deep"), 74 | errcode (ErrOverflow, "Overflow"), 75 | errcode (ErrRegexp, "Bad regular expression"), 76 | errcode (ErrDynamicUnsupported, "Dymanic link not supported"), 77 | errcode (ErrRepeatWithoutUntil, "REPEAT without UNTIL"), 78 | errcode (ErrUnexpectedFnEnd, "FN END outside DEF FN"), 79 | errcode (ErrNoFnEnd, "FN without FN END"), 80 | errcode (ErrDuplicateLabel, "Duplicate LABEL"), 81 | errcode (ErrNoTeDejo, "That won't work"), 82 | }; 83 | 84 | errcode * table_end= table + util::dim_array (table); 85 | 86 | class is_err { 87 | public: 88 | is_err (BlErrNo err) : err (err) 89 | { } 90 | bool operator () (const errcode & ec) const 91 | { return ec.err == err; } 92 | private: 93 | BlErrNo err; 94 | }; 95 | 96 | } // namespace 97 | 98 | //*********************************************** 99 | // class BlError 100 | //*********************************************** 101 | 102 | BlError::BlError () : 103 | err (ErrNoError) 104 | { } 105 | 106 | BlError::BlError (BlErrNo nerr) : 107 | err (nerr) 108 | { } 109 | 110 | BlError::BlError (BlErrNo nerr, ProgramPos npos) : 111 | err (nerr), 112 | pos (npos) 113 | { } 114 | 115 | void BlError::clear () 116 | { 117 | err= ErrNoError; 118 | pos= ProgramPos (); 119 | } 120 | 121 | void BlError::set (BlErrNo nerr, ProgramPos npos) 122 | { 123 | err= nerr; 124 | pos= npos; 125 | } 126 | 127 | void BlError::seterr (BlErrNo nerr) 128 | { 129 | err= nerr; 130 | } 131 | 132 | BlErrNo BlError::geterr () const 133 | { 134 | return err; 135 | } 136 | 137 | ProgramPos BlError::getpos () const 138 | { 139 | return pos; 140 | } 141 | 142 | std::ostream & operator << (std::ostream & os, const BlError & bl) 143 | { 144 | os << ErrStr (bl.err); 145 | const BlLineNumber line= bl.getpos ().getnum (); 146 | if (line != LineDirectCommand) 147 | os << " in " << line; 148 | //os << '\n'; 149 | return os; 150 | } 151 | 152 | //*********************************************** 153 | // class BlBreakInPos 154 | //*********************************************** 155 | 156 | BlBreakInPos::BlBreakInPos (ProgramPos pos) : 157 | pos (pos) 158 | { } 159 | 160 | ProgramPos BlBreakInPos::getpos () const 161 | { 162 | return pos; 163 | } 164 | 165 | std::ostream & operator << (std::ostream & os, const BlBreakInPos & bbip) 166 | { 167 | os << "**BREAK**"; 168 | BlLineNumber line= bbip.getpos ().getnum (); 169 | if (line != LineDirectCommand) 170 | os << " in " << line; 171 | return os; 172 | } 173 | 174 | //*********************************************** 175 | // Other functions 176 | //*********************************************** 177 | 178 | std::string ErrStr (BlErrNo err) 179 | { 180 | const errcode * perr= std::find_if (table, table_end, is_err (err) ); 181 | if (perr != table_end) 182 | return perr->str; 183 | std::ostringstream strbuf; 184 | strbuf << "Error " << err; 185 | return strbuf.str (); 186 | } 187 | 188 | bool showdebuginfo () 189 | { 190 | //return sysvar::getFlags1 () & sysvar::ShowDebugInfo; 191 | return sysvar::hasFlags1 (sysvar::ShowDebugInfo); 192 | } 193 | 194 | // Fin de error.cpp 195 | -------------------------------------------------------------------------------- /socket.cpp: -------------------------------------------------------------------------------- 1 | // socket.cpp 2 | // Revision 24-apr-2009 3 | 4 | #include "socket.h" 5 | 6 | #include 7 | 8 | //------------------------------------------------ 9 | // Changed this: now do not use winsock in Cygwin. 10 | //------------------------------------------------ 11 | //#if defined _Windows || defined __CYGWIN__ || defined __MINGW32__ 12 | // 13 | #if defined _Windows || defined __MINGW32__ 14 | 15 | #include 16 | 17 | typedef SOCKET TypeSocket; 18 | const TypeSocket InvalidSocket= INVALID_SOCKET; 19 | inline bool isInvalidSocket (TypeSocket s) 20 | { return s == INVALID_SOCKET; } 21 | 22 | namespace { 23 | 24 | class InitWinSock { 25 | InitWinSock () 26 | { 27 | WSADATA data; 28 | r= WSAStartup (0x0101, & data); 29 | } 30 | ~InitWinSock () 31 | { 32 | WSACleanup (); 33 | } 34 | int r; 35 | static InitWinSock init; 36 | struct avoid_ugly_warning { }; 37 | friend struct avoid_ugly_warning; 38 | }; 39 | 40 | InitWinSock InitWinSock::init; 41 | 42 | } // namespace 43 | 44 | #else 45 | 46 | #include 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | typedef int TypeSocket; 54 | const TypeSocket InvalidSocket= -1; 55 | inline bool isInvalidSocket (TypeSocket s) 56 | { return s < 0; } 57 | inline int closesocket (int handle) { return close (handle); } 58 | 59 | #endif 60 | 61 | #include 62 | 63 | #ifdef __BORLANDC__ 64 | #pragma warn -inl 65 | #endif 66 | 67 | 68 | //********************************************************** 69 | // SocketError 70 | //********************************************************** 71 | 72 | std::string SocketError::strErr= "Socket error in "; 73 | 74 | SocketError::SocketError (const std::string & nstr) 75 | { 76 | str= strErr; 77 | str+= nstr; 78 | } 79 | 80 | SocketError::SocketError (const std::string & nstr, int errnum) 81 | { 82 | str= strErr; 83 | str+= nstr; 84 | str+= ": "; 85 | str+= strerror (errnum); 86 | } 87 | 88 | const char * SocketError::what () const throw () 89 | { 90 | return str.c_str (); 91 | } 92 | 93 | //********************************************************** 94 | // Socket::Internal 95 | //********************************************************** 96 | 97 | class Socket::Internal { 98 | public: 99 | Internal () : 100 | refcount (1), s (InvalidSocket), maxbuf (0), posbuf (0) 101 | { 102 | } 103 | void addref () { ++refcount; } 104 | void delref () 105 | { 106 | if (--refcount == 0) { 107 | if (! isInvalidSocket (s) ) 108 | closesocket (s); 109 | delete this; 110 | } 111 | } 112 | void set (TypeSocket ns) { s= ns; } 113 | TypeSocket handle () { return s; } 114 | int connect (sockaddr * name, int namelen) 115 | { 116 | //if (! isInvalidSocket (s) ) 117 | // throw SocketError ("connect: already connected"); 118 | return ::connect (s, name, namelen); 119 | } 120 | bool eof () 121 | { 122 | if (posbuf < maxbuf) 123 | return false; 124 | getbuffer (); 125 | return maxbuf == 0; 126 | } 127 | int recv (char * bufrec, size_t len, int flags= 0); 128 | int send (const char * buffer, size_t len, int flags= 0) 129 | { 130 | return ::send (s, buffer, len, flags); 131 | } 132 | char get () 133 | { 134 | if (posbuf >= maxbuf) { 135 | getbuffer (); 136 | if (maxbuf == 0) return 0; 137 | } 138 | return buffer [posbuf++]; 139 | } 140 | private: 141 | size_t refcount; 142 | TypeSocket s; 143 | static const size_t bufsiz= 1024; 144 | char buffer [bufsiz]; 145 | size_t maxbuf, posbuf; 146 | void getbuffer () 147 | { 148 | posbuf= 0; 149 | maxbuf= 0; 150 | int i= ::recv (s, buffer, bufsiz, 0); 151 | if (i > 0) 152 | maxbuf= i; 153 | } 154 | }; 155 | 156 | int Socket::Internal::recv (char * bufrec, size_t len, int flags) 157 | { 158 | if (posbuf < maxbuf) { 159 | size_t send= maxbuf - posbuf; 160 | if (len < send) send= len; 161 | for (size_t i= 0, j= posbuf; i < send; ++i, ++j) 162 | bufrec [i]= buffer [j]; 163 | posbuf+= send; 164 | return send; 165 | } 166 | return ::recv (s, bufrec, len, flags); 167 | } 168 | 169 | //********************************************************** 170 | // Socket 171 | //********************************************************** 172 | 173 | Socket::Socket () 174 | { 175 | in= new Internal; 176 | } 177 | 178 | Socket::Socket (const Socket & nsock) 179 | { 180 | in= nsock.in; 181 | in->addref (); 182 | } 183 | 184 | Socket::~Socket () 185 | { 186 | in->delref (); 187 | } 188 | 189 | Socket & Socket::operator = (const Socket & nsock) 190 | { 191 | Internal * nin; 192 | nin= nsock.in; 193 | nin->addref (); 194 | in->delref (); 195 | in= nin; 196 | return * this; 197 | } 198 | 199 | #if 0 200 | TypeSocket Socket::handle () 201 | { 202 | return in->handle (); 203 | } 204 | #endif 205 | 206 | bool Socket::eof () 207 | { 208 | return in->eof (); 209 | } 210 | 211 | std::string Socket::readline () 212 | { 213 | char c; 214 | std::string str; 215 | while ( (c= in->get () ) != '\n' && c != '\0') 216 | str+= c; 217 | #if 0 218 | std::string::size_type l= str.size (); 219 | if (l > 0 && str [l - 1] == '\r') 220 | str.erase (l - 1); 221 | #endif 222 | return str; 223 | } 224 | 225 | int Socket::read (char * str, int len) 226 | { 227 | return in->recv (str, len); 228 | } 229 | 230 | void Socket::write (const std::string & str) 231 | { 232 | in->send (str.data (), str.size () ); 233 | } 234 | 235 | void Socket::write (const char * str, size_t len) 236 | { 237 | in->send (str, len); 238 | } 239 | 240 | //********************************************************** 241 | // TcpSocket 242 | //********************************************************** 243 | 244 | TcpSocket::TcpSocket () 245 | { 246 | protoent * pe= getprotobyname ("tcp"); 247 | int proto= pe ? pe->p_proto : 0; 248 | TypeSocket s= socket (PF_INET, SOCK_STREAM, proto); 249 | in->set (s); 250 | } 251 | 252 | //********************************************************** 253 | // TcpSocketClient 254 | //********************************************************** 255 | 256 | TcpSocketClient::TcpSocketClient 257 | (const std::string & host, unsigned short port) 258 | { 259 | hostent * hent= gethostbyname (host.c_str () ); 260 | if (! hent) 261 | throw SocketError (std::string ("search from host ") + host, 262 | errno); 263 | sockaddr_in addr; 264 | addr.sin_family= AF_INET; 265 | addr.sin_port= htons (port); 266 | addr.sin_addr= * (in_addr *) hent->h_addr_list [0]; 267 | if (in->connect ( (sockaddr *) & addr, sizeof (addr) ) != 0) 268 | throw SocketError (std::string ("connect with ") + host, 269 | errno); 270 | } 271 | 272 | // Fin de socket.cpp 273 | -------------------------------------------------------------------------------- /acinclude.m4: -------------------------------------------------------------------------------- 1 | # Configure paths for SVGAlib 2 | # Created by Pierre Sarrazin 3 | # Tiny changes by Julian Albo. 4 | # This file is in the public domain. 5 | # Created from sdl.m4. 6 | 7 | # This test must be executed in C mode (AC_LANG_C), not C++ mode. 8 | 9 | # Defines SVGALIB_CFLAGS and SVGALIB_LIBS and submits them to AC_SUBST() 10 | 11 | dnl AM_PATH_SVGALIB([MINIMUM-VERSION [,ACTION-IF-FOUND [,ACTION-IF-NOT-FOUND]]]) 12 | dnl Test for SVGAlib, and define SVGALIB_CFLAGS and SVGALIB_LIBS 13 | dnl 14 | AC_DEFUN(AM_PATH_SVGALIB, 15 | [ 16 | AC_ARG_WITH(svgalib-prefix, 17 | AC_HELP_STRING([--with-svgalib-prefix=PFX], 18 | [Prefix where SVGAlib is installed [[/usr]]] ), 19 | svgalib_prefix="$withval", 20 | svgalib_prefix="/usr" 21 | ) 22 | AC_MSG_RESULT([using $svgalib_prefix as SVGAlib prefix]) 23 | AC_ARG_ENABLE(svgalibtest, 24 | AC_HELP_STRING([--disable-svgalibtest], 25 | [Do not try to compile and run a test program] ), 26 | , 27 | enable_svgalibtest=yes 28 | ) 29 | 30 | dnl Changed this check. 31 | dnl AC_REQUIRE([AC_CANONICAL_TARGET]) 32 | AC_REQUIRE([AC_CANONICAL_HOST]) 33 | min_svgalib_version=ifelse([$1], ,1.4.0, $1) 34 | AC_MSG_CHECKING([for SVGAlib - version >= $min_svgalib_version]) 35 | no_svgalib="" 36 | 37 | 38 | if test "$svgalib_prefix" = /usr; then 39 | # Avoid the switch -I/usr/include - it might break gcc 3.x 40 | SVGALIB_CFLAGS= 41 | else 42 | SVGALIB_CFLAGS="-I$svgalib_prefix/include" 43 | fi 44 | 45 | SVGALIB_LIBS="-L$svgalib_prefix/lib -lvgagl -lvga" 46 | 47 | # Get the version number, which appears to be in the lib*.so.* filename: 48 | # 49 | if test -f $svgalib_prefix/lib/libvga.so.*.*.*; then 50 | 51 | _f=`echo $svgalib_prefix/lib/libvga.so.*.*.* | \ 52 | sed 's/^.*\.so\.//'` 53 | svgalib_major_version=`echo $_f | \ 54 | sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` 55 | svgalib_minor_version=`echo $_f | \ 56 | sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` 57 | svgalib_micro_version=`echo $_f | \ 58 | sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` 59 | 60 | unset _f 61 | 62 | else 63 | AC_MSG_ERROR([could not find $svgalib_prefix/lib/libvga.so.*.*.*]) 64 | fi 65 | 66 | if test "_$enable_svgalibtest" = "_yes" ; then 67 | ac_save_CFLAGS="$CFLAGS" 68 | ac_save_LIBS="$LIBS" 69 | CFLAGS="$CFLAGS $SVGALIB_CFLAGS" 70 | LIBS="$LIBS $SVGALIB_LIBS" 71 | dnl 72 | dnl Check if the installed SVGAlib is sufficiently new. 73 | dnl 74 | rm -f conf.svgalibtest 75 | AC_TRY_RUN([ 76 | #include 77 | #include 78 | #include 79 | #include "vga.h" 80 | 81 | char* 82 | my_strdup (char *str) 83 | { 84 | char *new_str; 85 | 86 | if (str) 87 | { 88 | new_str = (char *)malloc ((strlen (str) + 1) * sizeof(char)); 89 | strcpy (new_str, str); 90 | } 91 | else 92 | new_str = NULL; 93 | 94 | return new_str; 95 | } 96 | 97 | int main (int argc, char *argv[]) 98 | { 99 | int major, minor, micro; 100 | char *tmp_version; 101 | 102 | /* This hangs on some systems (?) 103 | system ("touch conf.svgalibtest"); 104 | */ 105 | { FILE *fp = fopen("conf.svgalibtest", "a"); if ( fp ) fclose(fp); } 106 | 107 | /* HP/UX 9 (%@#!) writes to sscanf strings */ 108 | tmp_version = my_strdup("$min_svgalib_version"); 109 | if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { 110 | printf("%s, bad version string\n", "$min_svgalib_version"); 111 | exit(1); 112 | } 113 | 114 | if (($svgalib_major_version > major) || 115 | (($svgalib_major_version == major) && ($svgalib_minor_version > minor)) || 116 | (($svgalib_major_version == major) && ($svgalib_minor_version == minor) && ($svgalib_micro_version >= micro))) 117 | { 118 | return 0; 119 | } 120 | else 121 | { 122 | printf("\n*** Installed SVGAlib version is %d.%d.%d, but the minimum version\n", $svgalib_major_version, $svgalib_minor_version, $svgalib_micro_version); 123 | printf("*** of SVGAlib required is %d.%d.%d.\n", major, minor, micro); 124 | printf("*** It is best to upgrade to the required version.\n"); 125 | printf("*** The web site is http://www.svgalib.org/\n"); 126 | printf("*** See also --with-svgalib-prefix\n"); 127 | return 1; 128 | } 129 | } 130 | 131 | ], 132 | , 133 | no_svgalib=yes, 134 | [echo $ac_n "cross compiling; assumed OK... $ac_c"] 135 | ) 136 | 137 | CFLAGS="$ac_save_CFLAGS" 138 | LIBS="$ac_save_LIBS" 139 | fi 140 | 141 | 142 | if test "_$no_svgalib" = _ ; then 143 | AC_MSG_RESULT([found $svgalib_major_version.$svgalib_minor_version.$svgalib_micro_version]) 144 | ifelse([$2], , :, [$2]) 145 | else 146 | AC_MSG_ERROR([SVGAlib >= min_svgalib_version not found]) 147 | 148 | if test -f conf.svgalibtest ; then 149 | : 150 | else 151 | echo "*** Could not run SVGAlib test program, checking why..." 152 | 153 | CFLAGS="$CFLAGS $SVGALIB_CFLAGS" 154 | LIBS="$LIBS $SVGALIB_LIBS" 155 | 156 | AC_TRY_LINK([ 157 | #include 158 | #include "vga.h" 159 | 160 | int main(int argc, char *argv[]) 161 | { return 0; } 162 | #undef main 163 | #define main K_and_R_C_main 164 | ], [ return 0; ], 165 | [ echo "*** The test program compiled, but did not run. This usually means" 166 | echo "*** that the run-time linker is not finding SVGAlib or finding the wrong" 167 | echo "*** version of SVGAlib. If it is not finding SVGAlib, you'll need to set your" 168 | echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" 169 | echo "*** to the installed location Also, make sure you have run ldconfig if that" 170 | echo "*** is required on your system" 171 | echo "***" 172 | echo "*** If you have an old version installed, it is best to remove it, although" 173 | echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" 174 | ], 175 | [ echo "*** The test program failed to compile or link. See the file config.log for the" 176 | echo "*** exact error that occured. This usually means SVGAlib was incorrectly installed" 177 | echo "*** or that you have moved SVGAlib since it was installed." 178 | echo "***" 179 | echo "*** SVGAlib web site: http://www.svgalib.org/" 180 | ] 181 | ) 182 | 183 | CFLAGS="$ac_save_CFLAGS" 184 | LIBS="$ac_save_LIBS" 185 | 186 | AC_MSG_ERROR([SVGAlib >= min_svgalib_version not found]) 187 | 188 | fi 189 | 190 | SVGALIB_CFLAGS="" 191 | SVGALIB_LIBS="" 192 | ifelse([$3], , :, [$3]) 193 | fi 194 | 195 | AC_SUBST(SVGALIB_CFLAGS) 196 | AC_SUBST(SVGALIB_LIBS) 197 | rm -f conf.svgalibtest 198 | ]) 199 | -------------------------------------------------------------------------------- /regexp.cpp: -------------------------------------------------------------------------------- 1 | // regexp.cpp 2 | // Revision 9-jan-2005 3 | 4 | #include "regexp.h" 5 | 6 | #include "blassic.h" 7 | #include "error.h" 8 | #include "trace.h" 9 | #include "runner.h" 10 | #include "runnerline.h" 11 | 12 | #include "util.h" 13 | using util::touch; 14 | 15 | #ifndef BLASSIC_USE_WINDOWS 16 | 17 | #include 18 | 19 | #include 20 | 21 | #endif 22 | 23 | //*********************************************** 24 | // Regexp::Internal 25 | //*********************************************** 26 | 27 | 28 | class Regexp::Internal { 29 | public: 30 | typedef Regexp::string string; 31 | typedef Regexp::size_type size_type; 32 | 33 | Internal (const string & exp, flag_t flags); 34 | ~Internal (); 35 | size_type find (const string & searched, size_type init); 36 | string replace (const string & searched, size_type init, 37 | const string & replaceby); 38 | string replace (const string & searched, size_type init, 39 | RunnerLine & runnerline, const string & fname); 40 | private: 41 | flag_t flags; 42 | #ifndef BLASSIC_USE_WINDOWS 43 | regex_t reg; 44 | #endif 45 | }; 46 | 47 | Regexp::Internal::Internal (const string & exp, flag_t flags) : 48 | flags (flags) 49 | { 50 | #ifdef BLASSIC_USE_WINDOWS 51 | 52 | touch (exp, flags); 53 | throw ErrNotImplemented; 54 | 55 | #else 56 | int cflags= REG_EXTENDED; 57 | if (flags & FLAG_NOCASE) 58 | cflags|= REG_ICASE; 59 | if (flags & FLAG_NEWLINE) 60 | cflags|= REG_NEWLINE; 61 | if (regcomp (& reg, exp.c_str (), cflags) != 0) 62 | throw ErrRegexp; 63 | 64 | #endif 65 | } 66 | 67 | Regexp::Internal::~Internal () 68 | { 69 | #ifndef BLASSIC_USE_WINDOWS 70 | 71 | regfree (& reg); 72 | 73 | #endif 74 | } 75 | 76 | Regexp::size_type Regexp::Internal::find (const string & searched, 77 | size_type init) 78 | { 79 | #ifdef BLASSIC_USE_WINDOWS 80 | 81 | touch (searched, init); 82 | throw ErrNotImplemented; 83 | 84 | #else 85 | 86 | regmatch_t match; 87 | int eflags= 0; 88 | if (flags & FLAG_NOBEG) 89 | eflags|= REG_NOTBOL; 90 | if (flags & FLAG_NOEND) 91 | eflags|= REG_NOTEOL; 92 | int r= regexec (& reg, searched.c_str () + init, 1, & match, eflags); 93 | switch (r) 94 | { 95 | case 0: 96 | return match.rm_so + init; 97 | case REG_NOMATCH: 98 | return std::string::npos; 99 | default: 100 | throw ErrRegexp; 101 | } 102 | 103 | return std::string::npos; 104 | 105 | #endif 106 | } 107 | 108 | Regexp::string Regexp::Internal::replace 109 | (const string & searched, size_type init, const string & replaceby) 110 | { 111 | #ifdef BLASSIC_USE_WINDOWS 112 | 113 | touch (searched, init, replaceby); 114 | throw ErrNotImplemented; 115 | 116 | #else 117 | 118 | TRACEFUNC (tr, "Regexp::Internal::replace"); 119 | 120 | const size_t nmatch= reg.re_nsub + 1; 121 | std::vector vmatch (nmatch); 122 | int eflags= 0; 123 | if (flags & FLAG_NOBEG) 124 | eflags|= REG_NOTBOL; 125 | if (flags & FLAG_NOEND) 126 | eflags|= REG_NOTEOL; 127 | int r= regexec (& reg, searched.c_str () + init, 128 | nmatch, & vmatch [0], eflags); 129 | switch (r) 130 | { 131 | case 0: 132 | break; 133 | case REG_NOMATCH: 134 | return searched; 135 | default: 136 | throw ErrRegexp; 137 | } 138 | 139 | #if 0 140 | TRMESSAGE (tr, "Coincidence list"); 141 | for (size_t i= 0; i < nmatch; ++i) 142 | { 143 | regoff_t ini= vmatch [i].rm_so; 144 | if (ini == regoff_t (-1) ) 145 | TRMESSAGE (tr, "(empty)"); 146 | else 147 | { 148 | regoff_t len= vmatch [i].rm_eo - ini; 149 | TRMESSAGE (tr, searched.substr (init + ini, len) ); 150 | } 151 | } 152 | TRMESSAGE (tr, "End of coincidence list"); 153 | #endif 154 | 155 | string replace= replaceby; 156 | size_type pos= replace.find ('$'); 157 | while (pos != std::string::npos) 158 | { 159 | //TRMESSAGE (tr, replace.substr (pos) ); 160 | 161 | if (pos == replace.size () - 1) 162 | break; 163 | char c= replace [pos + 1]; 164 | if (c == '$') 165 | { 166 | replace.erase (pos, 1); 167 | ++pos; 168 | } 169 | else 170 | { 171 | if (isdigit (c) ) 172 | { 173 | size_t n= c - '0'; 174 | if (n >= nmatch) 175 | replace.erase (pos, 2); 176 | else 177 | { 178 | regoff_t ini= vmatch [n].rm_so; 179 | if (ini == regoff_t (-1) ) 180 | { 181 | replace.erase (pos, 2); 182 | } 183 | else 184 | { 185 | regoff_t l= vmatch [n].rm_eo 186 | - ini; 187 | replace.replace (pos, 2, 188 | searched, init + ini, 189 | l); 190 | pos-= 2; 191 | pos+= l; 192 | } 193 | } 194 | } 195 | else 196 | pos+= 2; 197 | } 198 | pos= replace.find ('$', pos); 199 | } 200 | return searched.substr (0, vmatch [0].rm_so + init) + 201 | replace + 202 | searched.substr (vmatch [0].rm_eo + init); 203 | 204 | #endif 205 | } 206 | 207 | Regexp::string Regexp::Internal::replace 208 | (const string & searched, size_type init, 209 | RunnerLine & runnerline, const string & fname) 210 | { 211 | #ifdef BLASSIC_USE_WINDOWS 212 | 213 | touch (searched, init, runnerline, fname); 214 | throw ErrNotImplemented; 215 | 216 | #else 217 | 218 | TRACEFUNC (tr, "Regexp::Internal::replace"); 219 | 220 | const size_t nmatch= reg.re_nsub + 1; 221 | std::vector vmatch (nmatch); 222 | int eflags= 0; 223 | if (flags & FLAG_NOBEG) 224 | eflags|= REG_NOTBOL; 225 | if (flags & FLAG_NOEND) 226 | eflags|= REG_NOTEOL; 227 | int r= regexec (& reg, searched.c_str () + init, 228 | nmatch, & vmatch [0], eflags); 229 | switch (r) 230 | { 231 | case 0: 232 | break; 233 | case REG_NOMATCH: 234 | return searched; 235 | default: 236 | throw ErrRegexp; 237 | } 238 | 239 | Function f= Function::get (fname); 240 | LocalLevel ll; 241 | const ParameterList & param= f.getparam (); 242 | const size_t l= param.size (); 243 | for (size_t i= 0; i < l; ++i) 244 | { 245 | std::string var= param [i]; 246 | TRMESSAGE (tr, "paramter: " + var); 247 | 248 | std::string value; 249 | if (i < nmatch) 250 | { 251 | regoff_t ini= vmatch [i].rm_so; 252 | if (ini != regoff_t (-1) ) 253 | { 254 | regoff_t l= vmatch [i].rm_eo - ini; 255 | value= std::string (searched, ini + init, l); 256 | } 257 | } 258 | assignvarstring (var, value); 259 | } 260 | blassic::result::BlResult result; 261 | runnerline.callfn (f, fname, ll, result); 262 | 263 | return searched.substr (0, vmatch [0].rm_so + init) + 264 | result.str () + 265 | searched.substr (vmatch [0].rm_eo + init); 266 | 267 | #endif 268 | } 269 | 270 | //*********************************************** 271 | // Regexp 272 | //*********************************************** 273 | 274 | 275 | Regexp::Regexp (const string & exp, flag_t flags) : 276 | pin (new Internal (exp, flags) ) 277 | { 278 | } 279 | 280 | Regexp::~Regexp () 281 | { 282 | delete pin; 283 | } 284 | 285 | Regexp::size_type Regexp::find (const string & searched, size_type init) 286 | { 287 | return pin->find (searched, init); 288 | } 289 | 290 | Regexp::string Regexp::replace 291 | (const string & searched, size_type init, const string & replaceby) 292 | { 293 | return pin->replace (searched, init, replaceby); 294 | } 295 | 296 | Regexp::string Regexp::replace (const string & searched, size_type init, 297 | RunnerLine & runnerline, const string & fname) 298 | { 299 | return pin->replace (searched, init, runnerline, fname); 300 | } 301 | 302 | // End of regexp.cpp 303 | -------------------------------------------------------------------------------- /filewindow.cpp: -------------------------------------------------------------------------------- 1 | // filewindow.cpp 2 | // Revision 23-jan-2005 3 | 4 | #include "file.h" 5 | 6 | #include "blassic.h" 7 | #include "error.h" 8 | #include "graphics.h" 9 | #include "edit.h" 10 | 11 | #include "trace.h" 12 | 13 | namespace blassic { 14 | 15 | namespace file { 16 | 17 | //*********************************************** 18 | // BlFileWindow 19 | //*********************************************** 20 | 21 | class BlFileWindow : public BlFile { 22 | public: 23 | BlFileWindow (BlChannel ch); 24 | BlFileWindow (BlChannel ch, int x1, int x2, int y1, int y2); 25 | ~BlFileWindow (); 26 | void reset (int x1, int x2, int y1, int y2); 27 | bool isfile () const; 28 | bool istextwindow () const; 29 | virtual bool eof (); 30 | virtual void flush (); 31 | virtual size_t getwidth () const; 32 | virtual void movecharforward (); 33 | virtual void movecharforward (size_t n); 34 | virtual void movecharback (); 35 | virtual void movecharback (size_t n); 36 | virtual void movecharup (); 37 | virtual void movecharup (size_t n); 38 | virtual void movechardown (); 39 | virtual void movechardown (size_t n); 40 | virtual void showcursor (); 41 | virtual void hidecursor (); 42 | virtual std::string getkey (); 43 | virtual std::string inkey (); 44 | void getline (std::string & str, bool endline= true); 45 | std::string read (size_t n); 46 | void tab (); 47 | void tab (size_t n); 48 | void endline (); 49 | void gotoxy (int x, int y); 50 | virtual void setcolor (int color); 51 | virtual int getcolor (); 52 | virtual void setbackground (int color); 53 | virtual int getbackground (); 54 | virtual void cls (); 55 | std::string copychr (BlChar from, BlChar to); 56 | int pos (); 57 | int vpos (); 58 | void tag (); 59 | void tagoff (); 60 | bool istagactive (); 61 | void inverse (bool active); 62 | bool getinverse (); 63 | void bright (bool active); 64 | bool getbright (); 65 | bool poll (); 66 | void scroll (int nlines); 67 | private: 68 | void outstring (const std::string & str); 69 | void outchar (char c); 70 | 71 | BlChannel ch; 72 | }; 73 | 74 | BlFile * newBlFileWindow (BlChannel ch) 75 | { 76 | return new BlFileWindow (ch); 77 | } 78 | 79 | BlFile * newBlFileWindow (BlChannel ch, int x1, int x2, int y1, int y2) 80 | { 81 | return new BlFileWindow (ch, x1, x2, y1, y2); 82 | } 83 | 84 | BlFileWindow::BlFileWindow (BlChannel ch) : 85 | BlFile (OpenMode (Input | Output) ), 86 | ch (ch) 87 | { 88 | if (ch != 0) 89 | throw ErrBlassicInternal; 90 | } 91 | 92 | BlFileWindow::BlFileWindow (BlChannel ch, int x1, int x2, int y1, int y2) : 93 | BlFile (OpenMode (Input | Output) ), 94 | ch (ch) 95 | { 96 | graphics::definewindow (ch, x1, x2, y1, y2); 97 | } 98 | 99 | BlFileWindow::~BlFileWindow () 100 | { 101 | graphics::undefinewindow (ch); 102 | } 103 | 104 | void BlFileWindow::reset (int x1, int x2, int y1, int y2) 105 | { 106 | graphics::definewindow (ch, x1, x2, y1, y2); 107 | } 108 | 109 | bool BlFileWindow::isfile () const 110 | { 111 | return false; 112 | } 113 | 114 | bool BlFileWindow::istextwindow () const 115 | { 116 | return true; 117 | } 118 | 119 | bool BlFileWindow::eof () 120 | { 121 | return false; 122 | } 123 | 124 | void BlFileWindow::flush () 125 | { 126 | // Nothing to do 127 | } 128 | 129 | size_t BlFileWindow::getwidth () const 130 | { 131 | return graphics::getlinewidth (ch); 132 | } 133 | 134 | void BlFileWindow::movecharforward () 135 | { 136 | graphics::movecharforward (ch, 1); 137 | } 138 | 139 | void BlFileWindow::movecharforward (size_t n) 140 | { 141 | graphics::movecharforward (ch, n); 142 | } 143 | 144 | void BlFileWindow::movecharback () 145 | { 146 | graphics::movecharback (ch, 1); 147 | } 148 | 149 | void BlFileWindow::movecharback (size_t n) 150 | { 151 | graphics::movecharback (ch, n); 152 | } 153 | 154 | void BlFileWindow::movecharup () 155 | { 156 | graphics::movecharup (ch, 1); 157 | } 158 | 159 | void BlFileWindow::movecharup (size_t n) 160 | { 161 | graphics::movecharup (ch, n); 162 | } 163 | 164 | void BlFileWindow::movechardown () 165 | { 166 | graphics::movechardown (ch, 1); 167 | } 168 | 169 | void BlFileWindow::movechardown (size_t n) 170 | { 171 | graphics::movechardown (ch, n); 172 | } 173 | 174 | void BlFileWindow::showcursor () 175 | { 176 | graphics::showcursor (ch); 177 | } 178 | 179 | void BlFileWindow::hidecursor () 180 | { 181 | graphics::hidecursor (ch); 182 | } 183 | 184 | std::string BlFileWindow::getkey () 185 | { 186 | return graphics::getkey (); 187 | } 188 | 189 | std::string BlFileWindow::inkey () 190 | { 191 | return graphics::inkey (); 192 | } 193 | 194 | void BlFileWindow::getline (std::string & str, bool endline) 195 | { 196 | using blassic::edit::editline; 197 | 198 | std::string auxstr; 199 | int inicol= graphics::xpos (ch); 200 | while (! editline (* this, auxstr, 0, inicol, endline) ) 201 | continue; 202 | swap (str, auxstr); 203 | } 204 | 205 | std::string BlFileWindow::read (size_t) 206 | { 207 | throw ErrNotImplemented; 208 | } 209 | 210 | void BlFileWindow::tab () 211 | { 212 | graphics::tab (ch); 213 | } 214 | 215 | void BlFileWindow::tab (size_t n) 216 | { 217 | graphics::tab (ch, n); 218 | } 219 | 220 | void BlFileWindow::endline () 221 | { 222 | outstring ("\r\n"); 223 | } 224 | 225 | void BlFileWindow::gotoxy (int x, int y) 226 | { 227 | graphics::gotoxy (ch, x, y); 228 | } 229 | 230 | void BlFileWindow::setcolor (int color) 231 | { 232 | graphics::setcolor (ch, color); 233 | } 234 | 235 | int BlFileWindow::getcolor () 236 | { 237 | return graphics::getcolor (ch); 238 | } 239 | 240 | void BlFileWindow::setbackground (int color) 241 | { 242 | graphics::setbackground (ch, color); 243 | } 244 | 245 | int BlFileWindow::getbackground () 246 | { 247 | return graphics::getbackground (ch); 248 | } 249 | 250 | void BlFileWindow::outstring (const std::string & str) 251 | { 252 | TRACEFUNC (tr, "BlFileWindow::outstring"); 253 | TRMESSAGE (tr, str); 254 | 255 | graphics::stringout (ch, str); 256 | } 257 | 258 | void BlFileWindow::outchar (char c) 259 | { 260 | graphics::charout (ch, c); 261 | } 262 | 263 | void BlFileWindow::cls () 264 | { 265 | graphics::cls (ch); 266 | } 267 | 268 | std::string BlFileWindow::copychr (BlChar from, BlChar to) 269 | { 270 | return graphics::copychr (ch, from, to); 271 | } 272 | 273 | int BlFileWindow::pos () 274 | { 275 | return graphics::xpos (ch); 276 | } 277 | 278 | int BlFileWindow::vpos () 279 | { 280 | return graphics::ypos (ch); 281 | } 282 | 283 | void BlFileWindow::tag () 284 | { 285 | graphics::tag (ch); 286 | } 287 | 288 | void BlFileWindow::tagoff () 289 | { 290 | graphics::tagoff (ch); 291 | } 292 | 293 | bool BlFileWindow::istagactive () 294 | { 295 | return graphics::istagactive (ch); 296 | } 297 | 298 | void BlFileWindow::inverse (bool active) 299 | { 300 | graphics::inverse (ch, active); 301 | } 302 | 303 | bool BlFileWindow::getinverse () 304 | { 305 | return graphics::getinverse (ch); 306 | } 307 | 308 | void BlFileWindow::bright (bool active) 309 | { 310 | graphics::bright (ch, active); 311 | } 312 | 313 | bool BlFileWindow::getbright () 314 | { 315 | return graphics::getbright (ch); 316 | } 317 | 318 | bool BlFileWindow::poll () 319 | { 320 | return graphics::pollin (); 321 | } 322 | 323 | void BlFileWindow::scroll (int nlines) 324 | { 325 | graphics::scroll (ch, nlines); 326 | } 327 | 328 | } // namespace file 329 | 330 | } // namespace blassic 331 | 332 | // End of filewindow.cpp 333 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | # configure.ac for blassic 2 | 3 | AC_INIT(version.cpp) 4 | 5 | AC_CANONICAL_BUILD 6 | AC_CANONICAL_HOST 7 | 8 | # Require autoconf >= 2.50 9 | AC_PREREQ(2.50) 10 | 11 | # Parse version.cpp to get the version number. 12 | # The number is defined in version.cpp to avoid affecting the Windows 13 | # compilation process. 14 | # 15 | # Julian: changed the "grep -w Major" for "grep 'version::Major'" 16 | # because the -w option in not always present. 17 | 18 | AC_MSG_CHECKING(for version number in $srcdir/version.cpp) 19 | 20 | VERSION_MAJOR=`grep 'version::Major' $srcdir/version.cpp | \ 21 | sed 's/.*version::.*= *//;s/[[,;]]//'` 22 | VERSION_MINOR=`grep 'version::Minor' $srcdir/version.cpp | \ 23 | sed 's/.*version::.*= *//;s/[[,;]]//'` 24 | VERSION_RELEASE=`grep 'version::Release' $srcdir/version.cpp | \ 25 | sed 's/.*version::.*= *//;s/[[,;]]//'` 26 | 27 | AC_MSG_RESULT([got $VERSION_MAJOR.$VERSION_MINOR.$VERSION_RELEASE]) 28 | 29 | if test "_$VERSION_MAJOR" = "_"; then 30 | AC_MSG_ERROR([version::Major not found]) 31 | elif test "_$VERSION_MINOR" = "_"; then 32 | AC_MSG_ERROR([version::Minor not found]) 33 | elif test "_$VERSION_RELEASE" = "_"; then 34 | AC_MSG_ERROR([version::Release not found]) 35 | fi 36 | 37 | AM_INIT_AUTOMAKE(blassic, $VERSION_MAJOR.$VERSION_MINOR.$VERSION_RELEASE) 38 | 39 | # This is to check in the sources that configure has been used. 40 | AC_DEFINE([BLASSIC_CONFIG]) 41 | 42 | # Checks for programs. 43 | AC_PROG_CXX 44 | AC_LANG_CPLUSPLUS 45 | 46 | # Check if compiling for windows. 47 | case "$host" in 48 | *-*-cygwin*|*mingw*) 49 | HOST_WIN=1 50 | ;; 51 | *) 52 | ;; 53 | esac 54 | 55 | ############################################################################### 56 | 57 | # Option to disable graphics. 58 | 59 | AC_ARG_ENABLE(graphics, AC_HELP_STRING( 60 | [--enable-graphics], [Use graphics [[yes]]] ) ) 61 | if test "$enable_graphics" = "no"; then 62 | AC_MSG_RESULT([not using graphics]) 63 | AC_DEFINE(BLASSIC_CONFIG_NO_GRAPHICS) 64 | else 65 | AC_MSG_RESULT([using graphics]) 66 | fi 67 | 68 | ############################################################################### 69 | 70 | # Option to disable curses / ncurses. 71 | 72 | if test "_$HOST_WIN" != _1 73 | then 74 | AC_ARG_ENABLE(curses, AC_HELP_STRING( 75 | [--enable-curses], [Use curses [[yes]]] ) ) 76 | if test "$enable_curses" = "no"; then 77 | AC_MSG_RESULT([not using curses]) 78 | AC_DEFINE(BLASSIC_CONFIG_NO_CURSES) 79 | else 80 | AC_MSG_RESULT([using curses]) 81 | 82 | # Option to disable ncurses, checking only curses 83 | 84 | AC_ARG_ENABLE(curses, AC_HELP_STRING( 85 | [--enable-ncurses], 86 | [Check ncurses before curses [[yes]]] ) ) 87 | if test "$enable_ncurses" = "no"; then 88 | AC_MSG_RESULT([not checking ncurses]) 89 | AC_DEFINE(BLASSIC_CONFIG_NO_NCURSES) 90 | else 91 | AC_MSG_RESULT([checking ncurses]) 92 | fi 93 | 94 | fi 95 | fi 96 | 97 | ############################################################################### 98 | 99 | # Option to enable svgalib (actually unsupported). 100 | 101 | if test "_$HOST_WIN" != _1 102 | then 103 | AC_ARG_ENABLE(svgalib, AC_HELP_STRING( 104 | [--enable-svgalib], [Use svgalib [[yes]]] ), 105 | [ 106 | if test "_$enableval" = "_no"; then 107 | : 108 | AC_SUBST(SVGALIB_CFLAGS) 109 | AC_SUBST(SVGALIB_LIBS) 110 | else 111 | AM_PATH_SVGALIB(1.4.0) 112 | fi 113 | ], 114 | [ 115 | : 116 | AC_SUBST(SVGALIB_CFLAGS) 117 | AC_SUBST(SVGALIB_LIBS) 118 | ] 119 | ) 120 | if test "_$SVGALIB_LIBS" = "_"; then 121 | AC_MSG_RESULT([not using svgalib]) 122 | fi 123 | fi 124 | 125 | ############################################################################### 126 | 127 | # Check for cross-compiling: 128 | 129 | if test "$cross_compiling" = "yes" 130 | then 131 | if test "$CXX_FOR_BUILD" = "" 132 | then 133 | CXX_FOR_BUILD="g++" 134 | fi 135 | AC_SUBST(CXX_FOR_BUILD,[$CXX_FOR_BUILD]) 136 | if test "$CXXFLAGS_FOR_BUILD" = "" 137 | then 138 | CXXFLAGS_FOR_BUILD=$CXXFLGAS 139 | fi 140 | AC_SUBST(CXXFLAGS_FOR_BUILD,[$CXXFLAGS_FOR_BUILD]) 141 | else 142 | AC_SUBST(CXX_FOR_BUILD,[$CXX]) 143 | AC_SUBST(CXXFLAGS_FOR_BUILD,[$CXXFLAGS]) 144 | fi 145 | 146 | ############################################################################### 147 | 148 | # Check headers and libs. 149 | 150 | 151 | # Compatibility with old versions of C++ 152 | 153 | AC_CHECK_HEADERS([cstdlib]) 154 | 155 | 156 | # Cursor, graphics and printer. 157 | 158 | case "$host" in 159 | *-*-cygwin*|*mingw*) 160 | AC_SUBST(CYGWIN_FLAGS, ["-lgdi32 -lwsock32 -lwinspool"]) 161 | 162 | # isatty can be defined here or in unistd.h 163 | AC_CHECK_HEADERS([io.h]) 164 | ;; 165 | *) 166 | AC_SUBST(CYGWIN_FLAGS) 167 | 168 | # Check for sys/mman.h, needed for mmap. 169 | # This test seems to not work correctly when cross-compiling. 170 | #AC_FUNC_MMAP 171 | AC_CHECK_HEADERS([sys/mman.h], AC_DEFINE([HAVE_MMAP], 1) ) 172 | 173 | 174 | # If the systems has libdl, use it. 175 | AC_CHECK_LIB(dl, dlopen) 176 | 177 | # Check for ncurses, if not found for curses. 178 | # Done in a complicated way to work in all possible cases 179 | # and avoid to link both libs. 180 | if test "$enable_curses" != "no" 181 | then 182 | if test "$enable_ncurses" != "no" 183 | then 184 | AC_MSG_NOTICE([checking if ncurses or curses can be used]) 185 | else 186 | AC_MSG_NOTICE([checking if curses can be used]) 187 | fi 188 | if test "$enable_ncurses" != "no" 189 | then 190 | ncurses_found=yes 191 | AC_CHECK_HEADERS([ncurses.h],,[ncurses_found=no]) 192 | if test "$ncurses_found" = yes 193 | then 194 | AC_CHECK_LIB([ncurses],[tputs],,[ncurses_found=no]) 195 | if test "$ncurses_found" = yes 196 | then 197 | AC_DEFINE(BLASSIC_CONFIG_USE_NCURSES) 198 | AC_MSG_NOTICE([using ncurses]) 199 | else 200 | AC_MSG_WARN([ncurses header found but no lib]) 201 | fi 202 | fi 203 | fi 204 | if test "$ncurses_found" != yes 205 | then 206 | if test "$enable_ncurses" != "no" 207 | then 208 | AC_MSG_NOTICE([ncurses not available, checking curses]) 209 | fi 210 | curses_found=yes 211 | AC_CHECK_HEADERS([curses.h],,[curses_found=no]) 212 | if test "$curses_found" = yes 213 | then 214 | AC_CHECK_LIB(curses,tputs,,[curses_found=no]) 215 | if test "$curses_found" = yes 216 | then 217 | AC_DEFINE(BLASSIC_CONFIG_USE_CURSES) 218 | if test "$enable_ncurses" != "no" 219 | then 220 | AC_MSG_NOTICE([using curses]) 221 | fi 222 | else 223 | AC_MSG_WARN([curses header found but no lib]) 224 | fi 225 | fi 226 | fi 227 | if test "$ncurses_found" != yes && test "$curses_found" != yes 228 | then 229 | AC_MSG_NOTICE([not using curses]) 230 | fi 231 | AC_CHECK_HEADERS([term.h]) 232 | fi 233 | 234 | 235 | # Check X11. 236 | if test "$enable_graphics" != "no" 237 | then 238 | AC_PATH_XTRA 239 | if test "x$no_x" = xyes 240 | then 241 | AC_MSG_NOTICE([X not available or disabled, disabling graphics]) 242 | AC_DEFINE(BLASSIC_CONFIG_NO_GRAPHICS) 243 | else 244 | xflags="$X_CFLAGS" 245 | xlibs="$X_LIBS" 246 | xadd="$X_PRE_LIBS -lX11 $X_EXTRA_LIBS" 247 | fi 248 | fi 249 | AC_SUBST([BL_X_CFLAGS], [$xflags] ) 250 | AC_SUBST([BL_X_LIBS], [$xlibs] ) 251 | AC_SUBST([BL_X_ADD], [$xadd] ) 252 | 253 | AC_HEADER_SYS_WAIT 254 | 255 | # Check some variants used in debugging when available. 256 | AC_CHECK_MEMBERS([siginfo_t.si_ptr],,,[#include ]) 257 | 258 | ;; 259 | esac 260 | 261 | # Check availability of hyperbolic trigonometric functions. 262 | 263 | AC_CHECK_DECLS([asinh, acosh, atanh], , , [#include ] ) 264 | 265 | 266 | ############################################################################### 267 | 268 | 269 | AC_ARG_ENABLE(installed-examples, AC_HELP_STRING( 270 | [--enable-installed-examples], 271 | [Install the example programs [[yes]]] ), 272 | [ 273 | if test "_$enableval" = "_no"; then 274 | INSTALL_EXAMPLE_PROGS=no 275 | else 276 | INSTALL_EXAMPLE_PROGS=yes 277 | fi 278 | ], 279 | [ 280 | INSTALL_EXAMPLE_PROGS=yes 281 | ] 282 | ) 283 | 284 | AM_CONDITIONAL(INSTALL_EXAMPLE_PROGS, [test "_$INSTALL_EXAMPLE_PROGS" = _yes]) 285 | 286 | 287 | 288 | 289 | ############################################################################### 290 | 291 | # Generate files. 292 | AC_OUTPUT([ 293 | Makefile 294 | blassic.spec 295 | ]) 296 | -------------------------------------------------------------------------------- /runnerline_print.cpp: -------------------------------------------------------------------------------- 1 | // runnerline_print.cpp 2 | // Revision 7-feb-2005 3 | 4 | #include "runnerline_impl.h" 5 | 6 | #include "using.h" 7 | #include "sysvar.h" 8 | #include "util.h" 9 | using util::to_string; 10 | 11 | #include "trace.h" 12 | 13 | #include 14 | #define ASSERT assert 15 | 16 | namespace sysvar= blassic::sysvar; 17 | using namespace blassic::file; 18 | 19 | 20 | #define requiretoken(c) if (token.code == c) ; else throw ErrSyntax 21 | 22 | #define expecttoken(c) \ 23 | do { \ 24 | gettoken (); \ 25 | if (token.code != c) throw ErrSyntax; \ 26 | } while (0) 27 | 28 | void RunnerLineImpl::print_using (BlFile & out) 29 | { 30 | TRACEFUNC (tr, "RunnerLineImpl::print_using"); 31 | 32 | std::string format= expectstring (); 33 | VectorUsing usingf; 34 | parseusing (format, usingf); 35 | if (token.code == ',' || token.code == ';') 36 | gettoken (); 37 | const size_t l= usingf.size (); 38 | size_t ind= 0; 39 | Using * pf= usingf [ind]; 40 | for (;;) 41 | { 42 | if (ind == 0 && pf->isliteral () ) 43 | { 44 | pf->putliteral (out); 45 | ind= (ind + 1) % l; 46 | if (ind == 0) 47 | throw ErrFunctionCall; 48 | pf= usingf [ind]; 49 | } 50 | BlResult result; 51 | eval (result); 52 | switch (result.type () ) 53 | { 54 | case VarNumber: 55 | pf->putnumeric (out, result.number () ); 56 | break; 57 | case VarInteger: 58 | pf->putnumeric (out, result.number () ); 59 | break; 60 | case VarString: 61 | pf->putstring (out, result.str () ); 62 | break; 63 | default: 64 | ASSERT (false); 65 | throw ErrBlassicInternal; 66 | } 67 | ind= (ind + 1) % l; 68 | pf= usingf [ind]; 69 | if (ind != 0 && pf->isliteral () ) 70 | { 71 | pf->putliteral (out); 72 | ind= (ind + 1) % l; 73 | // Seen unnecessary, and is erroneous. 74 | //if (ind == 0) 75 | // throw ErrFunctionCall; 76 | pf= usingf [ind]; 77 | } 78 | if (endsentence () ) 79 | { 80 | //out << '\n'; 81 | out.endline (); 82 | break; 83 | } 84 | if (token.code == ';' || token.code == ',') 85 | { 86 | gettoken (); 87 | if (endsentence () ) 88 | break; 89 | } 90 | } 91 | } 92 | 93 | namespace { 94 | 95 | class ChannelSave { 96 | BlFile & bf; 97 | bool inversesaved; 98 | bool inversevalue; 99 | bool inksaved; 100 | int inkvalue; 101 | bool papersaved; 102 | int papervalue; 103 | bool brightsaved; 104 | bool brightvalue; 105 | public: 106 | ChannelSave (BlFile & bf) : 107 | bf (bf), 108 | inversesaved (false), 109 | inksaved (false), 110 | papersaved (false), 111 | brightsaved (false) 112 | { 113 | TRACEFUNC (tr, "ChannelSave::ChannelSave"); 114 | } 115 | ~ChannelSave () 116 | { 117 | TRACEFUNC (tr, "ChannelSave::~ChannelSave"); 118 | 119 | if (inversesaved) 120 | bf.inverse (inversevalue); 121 | if (brightsaved) 122 | bf.bright (brightvalue); 123 | if (inksaved) 124 | bf.setcolor (inkvalue); 125 | if (papersaved) 126 | bf.setbackground (papervalue); 127 | } 128 | void inverse (bool inv) 129 | { 130 | if (! inversesaved) 131 | { 132 | inversevalue= bf.getinverse (); 133 | inversesaved= true; 134 | } 135 | bf.inverse (inv); 136 | } 137 | void ink (int color) 138 | { 139 | if (! inksaved) 140 | { 141 | inkvalue= bf.getcolor (); 142 | inksaved= true; 143 | } 144 | bf.setcolor (color); 145 | } 146 | void paper (int color) 147 | { 148 | if (! papersaved) 149 | { 150 | papervalue= bf.getbackground (); 151 | papersaved= true; 152 | } 153 | bf.setbackground (color); 154 | } 155 | void bright (bool br) 156 | { 157 | if (! brightsaved) 158 | { 159 | brightvalue= bf.getbright (); 160 | brightsaved= true; 161 | } 162 | bf.bright (br); 163 | } 164 | }; 165 | 166 | } // namespace 167 | 168 | bool RunnerLineImpl::do_PRINT () 169 | { 170 | TRACEFUNC (tr, "RunnerLineImpl::do_PRINT"); 171 | 172 | // Same function used for PRINT and LPRINT, differing only 173 | // in the default channel. 174 | BlChannel channel= (token.code == keyLPRINT) ? 175 | PrinterChannel : DefaultChannel; 176 | gettoken (); 177 | if (token.code == '#') 178 | { 179 | channel= expectchannel (); 180 | // Allow ';' for Spectrum compatibility. 181 | if (token.code == ',' || token.code == ';') 182 | gettoken (); 183 | else 184 | require_endsentence (); 185 | } 186 | 187 | TRMESSAGE (tr, "Channel: " + to_string (channel) ); 188 | 189 | BlFile & out= getfile (channel); 190 | 191 | TRMESSAGE (tr, "Text window: " + to_string (out.istextwindow () ) ); 192 | TRMESSAGE (tr, "File: " + to_string (out.isfile () ) ); 193 | 194 | ChannelSave channelsave (out); 195 | 196 | if (token.code == '@') 197 | { 198 | BlResult result; 199 | expect (result); 200 | BlInteger pos= result.integer (); 201 | requiretoken (','); 202 | gettoken (); 203 | #if 0 204 | BlInteger row= (pos / 32) + 1; 205 | BlInteger col= (pos % 32) + 1; 206 | if (graphics::ingraphicsmode () ) 207 | graphics::locate (row, col); 208 | else 209 | locate (row, col); 210 | #else 211 | out.gotoxy (pos % 32, pos / 32); 212 | #endif 213 | } 214 | if (endsentence () ) 215 | { 216 | //out << '\n'; 217 | out.endline (); 218 | return false; 219 | } 220 | 221 | bool spacebeforenumber= 222 | sysvar::hasFlags1 (sysvar::SpaceBefore); 223 | BlResult result; 224 | size_t n; 225 | bool ended= false; 226 | do { 227 | switch (token.code) { 228 | case ',': 229 | case ';': 230 | // Separators can be before any statement, 231 | break; 232 | case keyUSING: 233 | print_using (out); 234 | ended= true; 235 | break; 236 | case keyTAB: 237 | //getparenarg (result); 238 | // Not required to improve Sinclair ZX compatibility. 239 | expect (result); 240 | n= result.integer (); 241 | if (! sysvar::hasFlags1 (sysvar::TabStyle) ) 242 | n-= 1; 243 | out.tab (n); 244 | break; 245 | case keySPC: 246 | getparenarg (result); 247 | n= result.integer (); 248 | //out << std::string (n, ' '); 249 | out.putspaces (n); 250 | break; 251 | case keyAT: 252 | out.flush (); 253 | { 254 | expect (result); 255 | //BlInteger row= result.integer () + 1; 256 | BlInteger row= result.integer (); 257 | requiretoken (','); 258 | expect (result); 259 | //BlInteger col= result.integer () + 1; 260 | BlInteger col= result.integer (); 261 | #if 0 262 | if (graphics::ingraphicsmode () ) 263 | graphics::locate (row, col); 264 | else 265 | locate (row, col); 266 | #else 267 | out.gotoxy (col, row); 268 | #endif 269 | } 270 | break; 271 | case keyINK: 272 | out.flush (); 273 | { 274 | BlInteger color= expectinteger (); 275 | channelsave.ink (color); 276 | } 277 | break; 278 | case keyPAPER: 279 | out.flush (); 280 | { 281 | BlInteger color= expectinteger (); 282 | channelsave.paper (color); 283 | } 284 | break; 285 | case keyINVERSE: 286 | out.flush (); 287 | { 288 | BlInteger inv= expectinteger (); 289 | channelsave.inverse (inv); 290 | } 291 | break; 292 | case keyBRIGHT: 293 | out.flush (); 294 | { 295 | BlInteger br= expectinteger (); 296 | channelsave.bright (br); 297 | } 298 | break; 299 | default: 300 | eval (result); 301 | switch (result.type () ) { 302 | case VarString: 303 | { 304 | TRMESSAGE (tr, "string"); 305 | std::string txt= result.str (); 306 | TRMESSAGE (tr, txt); 307 | //out << result.str (); 308 | out << txt; 309 | } 310 | break; 311 | case VarNumber: 312 | { 313 | BlNumber n= result.number (); 314 | if (spacebeforenumber && n >= 0) 315 | out << ' '; 316 | out << n; 317 | } 318 | break; 319 | case VarInteger: 320 | { 321 | BlInteger n= result.integer (); 322 | if (spacebeforenumber && n >= 0) 323 | out << ' '; 324 | out << n; 325 | } 326 | break; 327 | default: 328 | ASSERT (false); 329 | throw ErrBlassicInternal; 330 | } 331 | } 332 | if (ended) 333 | break; 334 | if (endsentence () ) 335 | { 336 | //out << '\n'; 337 | out.endline (); 338 | break; 339 | } 340 | #if 0 341 | if (token.code != ';' && token.code != ',') 342 | throw ErrSyntax; 343 | if (token.code == ',') 344 | out.tab (); 345 | gettoken (); 346 | #else 347 | // Now separator is not required 348 | switch (token.code) 349 | { 350 | case ',': 351 | out.tab (); 352 | gettoken (); 353 | break; 354 | case ';': 355 | gettoken (); 356 | break; 357 | default: 358 | ; // Nothing 359 | } 360 | #endif 361 | } while (! endsentence () ); 362 | TRMESSAGE (tr, "Flushing channel"); 363 | out.flush (); 364 | return false; 365 | } 366 | 367 | // End of runnerline_print.cpp 368 | -------------------------------------------------------------------------------- /keyword.cpp: -------------------------------------------------------------------------------- 1 | // keyword.cpp 2 | // Revision 7-feb-2005 3 | 4 | #include "keyword.h" 5 | #include "util.h" 6 | #include "sysvar.h" 7 | #include "trace.h" 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | // I don't understand why, but with this using the older version 17 | // of C++ Builder fails. 18 | #if __BORLANDC__ >= 0x0560 19 | using std::toupper; 20 | #endif 21 | 22 | namespace sysvar= blassic::sysvar; 23 | using util::dim_array; 24 | 25 | 26 | namespace { 27 | 28 | struct keycode { 29 | std::string key; 30 | BlCode code; 31 | keycode (const char * str, BlCode c) : 32 | key (str), code (c) 33 | { } 34 | }; 35 | 36 | // Can't declare const on Borland or fail at instantiate find_if, 37 | // don't know why. 38 | #ifdef __BORLANDC__ 39 | #define const_keycode keycode 40 | #else 41 | #define const_keycode const keycode 42 | #endif 43 | 44 | #define m_keycode(n) keycode (#n, key ## n) 45 | 46 | #define m_keycode_s(n) keycode (#n "$", key ## n ## _S) 47 | 48 | const_keycode table []= { 49 | m_keycode (END), 50 | m_keycode (LIST), 51 | m_keycode (REM), 52 | m_keycode (LOAD), 53 | m_keycode (SAVE), 54 | m_keycode (EXIT), 55 | m_keycode (NEW), 56 | m_keycode (RUN), 57 | m_keycode (PRINT), 58 | m_keycode (FOR), 59 | m_keycode (NEXT), 60 | m_keycode (TO), 61 | m_keycode (STEP), 62 | m_keycode (IF), 63 | m_keycode (THEN), 64 | m_keycode (ELSE), 65 | m_keycode (TRON), 66 | m_keycode (TROFF), 67 | m_keycode (LET), 68 | m_keycode (GOTO), 69 | m_keycode (STOP), 70 | m_keycode (CONT), 71 | m_keycode (CLEAR), 72 | m_keycode (GOSUB), 73 | m_keycode (RETURN), 74 | m_keycode (POKE), 75 | m_keycode (DATA), 76 | m_keycode (READ), 77 | m_keycode (RESTORE), 78 | m_keycode (INPUT), 79 | m_keycode (LINE), 80 | m_keycode (RANDOMIZE), 81 | m_keycode (PLEASE), 82 | m_keycode (AUTO), 83 | m_keycode (DIM), 84 | m_keycode (SYSTEM), 85 | m_keycode (ON), 86 | m_keycode (ERROR), 87 | m_keycode (OPEN), 88 | m_keycode (CLOSE), 89 | m_keycode (OUTPUT), 90 | m_keycode (AS), 91 | m_keycode (LOCATE), 92 | m_keycode (CLS), 93 | m_keycode (APPEND), 94 | m_keycode (WRITE), 95 | m_keycode (MODE), 96 | m_keycode (MOVE), 97 | m_keycode (COLOR), 98 | m_keycode (GET), 99 | m_keycode (LABEL), 100 | m_keycode (DELIMITER), 101 | m_keycode (REPEAT), 102 | m_keycode (UNTIL), 103 | m_keycode (WHILE), 104 | m_keycode (WEND), 105 | m_keycode (PLOT), 106 | m_keycode (POPEN), 107 | m_keycode (RESUME), 108 | m_keycode (DELETE), 109 | m_keycode (LOCAL), 110 | m_keycode (RANDOM), 111 | m_keycode (PUT), 112 | m_keycode (FIELD), 113 | m_keycode (LSET), 114 | m_keycode (RSET), 115 | m_keycode (SOCKET), 116 | m_keycode (DRAW), 117 | m_keycode (DEF), 118 | m_keycode (FN), 119 | m_keycode (ERASE), 120 | m_keycode (SWAP), 121 | m_keycode (SYMBOL), 122 | m_keycode (ZONE), 123 | m_keycode (POP), 124 | m_keycode (NAME), 125 | m_keycode (KILL), 126 | m_keycode (FILES), 127 | m_keycode (PAPER), 128 | m_keycode (PEN), 129 | m_keycode (SHELL), 130 | m_keycode (MERGE), 131 | m_keycode (CHDIR), 132 | m_keycode (MKDIR), 133 | m_keycode (RMDIR), 134 | m_keycode (BREAK), 135 | m_keycode (SYNCHRONIZE), 136 | m_keycode (PAUSE), 137 | m_keycode (CHAIN), 138 | m_keycode (STR), 139 | m_keycode (REAL), 140 | m_keycode (ENVIRON), 141 | m_keycode (EDIT), 142 | m_keycode (DRAWR), 143 | m_keycode (PLOTR), 144 | m_keycode (MOVER), 145 | m_keycode (POKE16), 146 | m_keycode (POKE32), 147 | m_keycode (RENUM), 148 | m_keycode (CIRCLE), 149 | m_keycode (MASK), 150 | m_keycode (WINDOW), 151 | m_keycode (GRAPHICS), 152 | m_keycode (AFTER), 153 | m_keycode (BEEP), 154 | m_keycode (DEFINT), 155 | m_keycode (DEFSTR), 156 | m_keycode (DEFREAL), 157 | m_keycode (DEFSNG), 158 | m_keycode (DEFDBL), 159 | m_keycode (INK), 160 | m_keycode (SET_TITLE), 161 | m_keycode (TAG), 162 | m_keycode (TAGOFF), 163 | m_keycode (ORIGIN), 164 | m_keycode (DEG), 165 | m_keycode (RAD), 166 | m_keycode (INVERSE), 167 | m_keycode (IF_DEBUG), 168 | m_keycode (LPRINT), 169 | m_keycode (LLIST), 170 | m_keycode (WIDTH), 171 | m_keycode (BRIGHT), 172 | m_keycode (BINARY), 173 | m_keycode (DRAWARC), 174 | m_keycode (PULL), 175 | m_keycode (PAINT), 176 | m_keycode (FREE_MEMORY), 177 | m_keycode (SCROLL), 178 | m_keycode (ZX_PLOT), 179 | m_keycode (ZX_UNPLOT), 180 | 181 | m_keycode_s (MID), 182 | m_keycode_s (LEFT), 183 | m_keycode_s (RIGHT), 184 | m_keycode_s (CHR), 185 | m_keycode_s (ENVIRON), 186 | m_keycode_s (STRING), 187 | m_keycode_s (OSFAMILY), 188 | m_keycode_s (HEX), 189 | m_keycode_s (SPACE), 190 | m_keycode_s (UPPER), 191 | m_keycode_s (LOWER), 192 | m_keycode_s (STR), 193 | m_keycode_s (OCT), 194 | m_keycode_s (BIN), 195 | m_keycode_s (INKEY), 196 | m_keycode_s (PROGRAMARG), 197 | m_keycode_s (DATE), 198 | m_keycode_s (TIME), 199 | m_keycode_s (INPUT), 200 | m_keycode_s (MKI), 201 | m_keycode_s (MKS), 202 | m_keycode_s (MKD), 203 | m_keycode_s (MKL), 204 | m_keycode_s (TRIM), 205 | m_keycode_s (LTRIM), 206 | m_keycode_s (RTRIM), 207 | m_keycode_s (OSNAME), 208 | m_keycode_s (FINDFIRST), 209 | m_keycode_s (FINDNEXT), 210 | m_keycode_s (COPYCHR), 211 | m_keycode_s (STRERR), 212 | m_keycode_s (DEC), 213 | m_keycode_s (VAL), 214 | m_keycode_s (SCREEN), 215 | m_keycode_s (MKSMBF), 216 | m_keycode_s (MKDMBF), 217 | m_keycode_s (REGEXP_REPLACE), 218 | m_keycode_s (UCASE), 219 | m_keycode_s (LCASE), 220 | 221 | m_keycode (ASC), 222 | m_keycode (LEN), 223 | m_keycode (PEEK), 224 | m_keycode (PROGRAMPTR), 225 | m_keycode (RND), 226 | m_keycode (INT), 227 | m_keycode (SIN), 228 | m_keycode (COS), 229 | m_keycode (PI), 230 | m_keycode (TAN), 231 | m_keycode (SQR), 232 | m_keycode (ASIN), 233 | m_keycode (ACOS), 234 | m_keycode (INSTR), 235 | m_keycode (ATAN), 236 | m_keycode (ABS), 237 | m_keycode (USR), 238 | m_keycode (VAL), 239 | m_keycode (EOF), 240 | m_keycode (VARPTR), 241 | m_keycode (SYSVARPTR), 242 | m_keycode (SGN), 243 | m_keycode (LOG), 244 | m_keycode (LOG10), 245 | m_keycode (EXP), 246 | m_keycode (TIME), 247 | m_keycode (ERR), 248 | m_keycode (ERL), 249 | m_keycode (CVI), 250 | m_keycode (CVS), 251 | m_keycode (CVD), 252 | m_keycode (CVL), 253 | m_keycode (MIN), 254 | m_keycode (MAX), 255 | m_keycode (CINT), 256 | m_keycode (FIX), 257 | m_keycode (XMOUSE), 258 | m_keycode (YMOUSE), 259 | m_keycode (XPOS), 260 | m_keycode (YPOS), 261 | m_keycode (PEEK16), 262 | m_keycode (PEEK32), 263 | m_keycode (RINSTR), 264 | m_keycode (FIND_FIRST_OF), 265 | m_keycode (FIND_LAST_OF), 266 | m_keycode (FIND_FIRST_NOT_OF), 267 | m_keycode (FIND_LAST_NOT_OF), 268 | m_keycode (SINH), 269 | m_keycode (COSH), 270 | m_keycode (TANH), 271 | m_keycode (ASINH), 272 | m_keycode (ACOSH), 273 | m_keycode (ATANH), 274 | m_keycode (ATAN2), 275 | m_keycode (TEST), 276 | m_keycode (TESTR), 277 | m_keycode (POS), 278 | m_keycode (VPOS), 279 | m_keycode (LOF), 280 | m_keycode (FREEFILE), 281 | m_keycode (INKEY), 282 | m_keycode (ROUND), 283 | m_keycode (CVSMBF), 284 | m_keycode (CVDMBF), 285 | m_keycode (REGEXP_INSTR), 286 | m_keycode (ALLOC_MEMORY), 287 | m_keycode (LOC), 288 | 289 | m_keycode (NOT), 290 | m_keycode (OR), 291 | m_keycode (AND), 292 | m_keycode (TAB), 293 | m_keycode (SPC), 294 | m_keycode (AT), 295 | m_keycode (XOR), 296 | m_keycode (MOD), 297 | m_keycode (USING), 298 | 299 | keycode ("<>", keyDISTINCT), 300 | keycode ("<=", keyMINOREQUAL), 301 | keycode (">=", keyGREATEREQUAL), 302 | keycode ("=<", keyEQUALMINOR), 303 | keycode ("=>", keyEQUALGREATER), 304 | keycode ("><", keyGREATERMINOR), 305 | 306 | // table_end points here, then if find_if (table, table_end, ...) 307 | // fails the result is: 308 | keycode ("???", 0) 309 | }; 310 | 311 | const_keycode * table_end= table + dim_array (table) - 1; 312 | 313 | class key_is : public std::unary_function { 314 | public: 315 | key_is (const std::string & str) : str (str) 316 | { } 317 | bool operator () (const keycode & k) const 318 | { return k.key == str; } 319 | private: 320 | const std::string & str; 321 | }; 322 | 323 | class code_is : public std::unary_function { 324 | public: 325 | code_is (BlCode code) : code (code) 326 | { } 327 | bool operator () (const keycode & k) const 328 | { return k.code == code; } 329 | private: 330 | BlCode code; 331 | }; 332 | 333 | inline std::string stringupper (const std::string & str) 334 | { 335 | std::string u (str.size (), 0); 336 | std::transform (str.begin (), str.end (), u.begin (), toupper); 337 | return u; 338 | } 339 | 340 | std::set exclude; 341 | 342 | } // namespace 343 | 344 | void excludekeyword (const std::string & str) 345 | { 346 | TRACEFUNC (tr, "excludekeyword"); 347 | 348 | std::string stru= stringupper (str); 349 | if (find_if (table, table_end, key_is (stru) ) != table_end) 350 | { 351 | exclude.insert (stru); 352 | TRMESSAGE (tr, std::string ("Excluding ") + stru); 353 | } 354 | } 355 | 356 | BlCode keyword (const std::string & str) 357 | { 358 | std::string stru= stringupper (str); 359 | BlCode code= std::find_if (table, table_end, key_is (stru) )->code; 360 | if (code != 0) 361 | if (exclude.find (stru) != exclude.end () ) 362 | return 0; 363 | return code; 364 | } 365 | 366 | std::string decodekeyword (BlCode s) 367 | { 368 | if (s == keyGOTO || s == keyGOSUB) 369 | { 370 | if (sysvar::hasFlags2 (sysvar::SeparatedGoto) ) 371 | return (s == keyGOTO) ? 372 | "GO TO" : 373 | "GO SUB"; 374 | } 375 | return std::find_if (table, table_end, code_is (s) )->key; 376 | } 377 | 378 | // Fin de keyword.cpp 379 | -------------------------------------------------------------------------------- /keyword.h: -------------------------------------------------------------------------------- 1 | #ifndef INCLUDE_BLASSIC_KEYWORD_H 2 | #define INCLUDE_BLASSIC_KEYWORD_H 3 | 4 | // keyword.h 5 | // Revision 9-jan-2005 6 | 7 | #include "blassic.h" 8 | 9 | const BlCode 10 | keyColon= ':', 11 | keyPlus= '+', 12 | keyMinus= '-', 13 | keyMult= '*', 14 | keyDiv= '/', 15 | keyDivInt= '\\', 16 | keyEqual= '=', 17 | keyMinor= '<', 18 | keyGreater= '>', 19 | keyOpenPar= '(', 20 | keyClosePar= ')', 21 | keyComma= ',', 22 | keySharp= '#', 23 | keyPower= '^', 24 | 25 | keyEND= 0x0101, 26 | keyLIST= 0x0102, 27 | keyREM= 0x0103, 28 | keyLOAD= 0x0104, 29 | keySAVE= 0x0105, 30 | keyNEW= 0x0106, 31 | keyEXIT= 0x0107, 32 | keyRUN= 0x0108, 33 | keyPRINT= 0x0109, 34 | keyFOR= 0x010A, 35 | keyNEXT= 0x010B, 36 | keyTO= 0x010C, 37 | keySTEP= 0x010D, 38 | keyIF= 0x010E, 39 | keyTHEN= 0x010F, 40 | keyELSE= 0x0110, 41 | keyTRON= 0x0111, 42 | keyTROFF= 0x0112, 43 | keyLET= 0x0113, 44 | keyGOTO= 0x0114, 45 | keySTOP= 0x0115, 46 | keyCONT= 0x0116, 47 | keyCLEAR= 0x0117, 48 | keyGOSUB= 0x0118, 49 | keyRETURN= 0x0119, 50 | keyPOKE= 0x011A, 51 | keyDATA= 0x011B, 52 | keyREAD= 0x011C, 53 | keyRESTORE= 0x011D, 54 | keyINPUT= 0x011E, 55 | keyLINE= 0x011F, 56 | keyRANDOMIZE= 0x0120, 57 | keyPLEASE= 0x0121, 58 | keyAUTO= 0x0122, 59 | keyDIM= 0x0123, 60 | keySYSTEM= 0x0124, 61 | keyON= 0x0125, 62 | keyERROR= 0x0126, 63 | keyOPEN= 0x0127, 64 | keyCLOSE= 0x0128, 65 | keyOUTPUT= 0x0129, 66 | keyAS= 0x012A, 67 | keyLOCATE= 0x012B, 68 | keyCLS= 0x012C, 69 | keyAPPEND= 0x012D, 70 | keyWRITE= 0x012E, 71 | keyMODE= 0x012F, 72 | keyMOVE= 0x0130, 73 | keyCOLOR= 0x0131, 74 | keyGET= 0x0132, 75 | keyLABEL= 0x0133, 76 | keyDELIMITER= 0x0134, 77 | keyREPEAT= 0x0135, 78 | keyUNTIL= 0x0136, 79 | keyWHILE= 0x0137, 80 | keyWEND= 0x0138, 81 | keyPLOT= 0x0139, 82 | keyPOPEN= 0x013A, 83 | keyRESUME= 0x013B, 84 | keyDELETE= 0x013C, 85 | keyLOCAL= 0x013D, 86 | keyRANDOM= 0x013E, 87 | keyPUT= 0x013F, 88 | keyFIELD= 0x0140, 89 | keyLSET= 0x0141, 90 | keyRSET= 0x0142, 91 | keySOCKET= 0x0143, 92 | keyDRAW= 0x0144, 93 | keyDEF= 0x0145, 94 | keyFN= 0x0146, 95 | keyERASE= 0x0147, 96 | keySWAP= 0x0148, 97 | keySYMBOL= 0x0149, 98 | keyZONE= 0x014A, 99 | keyPOP= 0x014B, 100 | keyNAME= 0x014C, 101 | keyKILL= 0x014D, 102 | keyFILES= 0x014E, 103 | keyPAPER= 0x014F, 104 | keyPEN= 0x0150, 105 | keySHELL= 0x0151, 106 | keyMERGE= 0x0152, 107 | keyCHDIR= 0x0153, 108 | keyMKDIR= 0x0154, 109 | keyRMDIR= 0x0155, 110 | keyBREAK= 0x0156, 111 | keySYNCHRONIZE= 0x0157, 112 | keyPAUSE= 0x0158, 113 | keyCHAIN= 0x0159, 114 | keySTR= 0x015A, 115 | keyREAL= 0x015B, 116 | keyENVIRON= 0x015C, 117 | keyEDIT= 0x015D, 118 | keyDRAWR= 0x015E, 119 | keyPLOTR= 0x015F, 120 | keyMOVER= 0x0160, 121 | keyPOKE16= 0x0161, 122 | keyPOKE32= 0x0162, 123 | keyRENUM= 0x0163, 124 | keyCIRCLE= 0x0164, 125 | keyMASK= 0x0165, 126 | keyWINDOW= 0x0166, 127 | keyGRAPHICS= 0x0167, 128 | keyAFTER= 0x0168, 129 | keyBEEP= 0x0169, 130 | keyDEFINT= 0x016A, 131 | keyDEFSTR= 0x016B, 132 | keyDEFREAL= 0x016C, 133 | keyDEFSNG= 0x016D, 134 | keyDEFDBL= 0x016E, 135 | keyINK= 0x016F, 136 | keySET_TITLE= 0x0170, 137 | keyTAG= 0x0171, 138 | keyTAGOFF= 0x0172, 139 | keyORIGIN= 0x0173, 140 | keyDEG= 0x0174, 141 | keyRAD= 0x0175, 142 | keyINVERSE= 0x0176, 143 | keyIF_DEBUG= 0x0177, 144 | keyLPRINT= 0x0178, 145 | keyLLIST= 0x0179, 146 | keyWIDTH= 0x017A, 147 | keyBRIGHT= 0x017B, 148 | keyBINARY= 0x017C, 149 | keyDRAWARC= 0x017D, 150 | keyPULL= 0x017E, 151 | keyPAINT= 0x017F, 152 | keyFREE_MEMORY= 0x0180, 153 | keySCROLL= 0x0181, 154 | keyZX_PLOT= 0x0182, 155 | keyZX_UNPLOT= 0x0183, 156 | 157 | keyMID_S= 0x0201, 158 | keyLEFT_S= 0x0202, 159 | keyRIGHT_S= 0x0203, 160 | keyCHR_S= 0x0204, 161 | keyENVIRON_S= 0x0205, 162 | keySTRING_S= 0x0206, 163 | keyOSFAMILY_S= 0x0207, 164 | keyHEX_S= 0x0208, 165 | keySPACE_S= 0x0209, 166 | keyUPPER_S= 0x020A, 167 | keyLOWER_S= 0x020B, 168 | keySTR_S= 0x020C, 169 | keyOCT_S= 0x020D, 170 | keyBIN_S= 0x020E, 171 | keyINKEY_S= 0x020F, 172 | keyPROGRAMARG_S= 0x0210, 173 | keyDATE_S= 0x0211, 174 | keyTIME_S= 0x0212, 175 | keyINPUT_S= 0x0213, 176 | keyMKI_S= 0x0214, 177 | keyMKS_S= 0x0215, 178 | keyMKD_S= 0x0216, 179 | keyMKL_S= 0x0217, 180 | keyTRIM_S= 0x0218, 181 | keyLTRIM_S= 0x0219, 182 | keyRTRIM_S= 0x021A, 183 | keyOSNAME_S= 0x021B, 184 | keyFINDFIRST_S= 0x021C, 185 | keyFINDNEXT_S= 0x021D, 186 | keyCOPYCHR_S= 0x021E, 187 | keySTRERR_S= 0x021F, 188 | keyDEC_S= 0x0220, 189 | keyVAL_S= 0x0221, 190 | keySCREEN_S= 0x0222, 191 | keyMKSMBF_S= 0x0223, 192 | keyMKDMBF_S= 0x0224, 193 | keyREGEXP_REPLACE_S= 0x0225, 194 | keyUCASE_S= 0x0226, 195 | keyLCASE_S= 0x0227, 196 | 197 | keyASC= 0x0301, 198 | keyLEN= 0x0302, 199 | keyPEEK= 0x0303, 200 | keyPROGRAMPTR= 0x0304, 201 | keyRND= 0x0305, 202 | keyINT= 0x0306, 203 | keySIN= 0x0307, 204 | keyCOS= 0x0308, 205 | keyPI= 0x0309, 206 | keyTAN= 0x030A, 207 | keySQR= 0x030B, 208 | keyASIN= 0x030C, 209 | keyACOS= 0x030D, 210 | keyINSTR= 0x030E, 211 | keyATAN= 0x030F, 212 | keyABS= 0x0310, 213 | keyUSR= 0x0311, 214 | keyVAL= 0x0312, 215 | keyEOF= 0x0313, 216 | keyVARPTR= 0x0314, 217 | keySYSVARPTR= 0x0315, 218 | keySGN= 0x0316, 219 | keyLOG= 0x0317, 220 | keyLOG10= 0x0318, 221 | keyEXP= 0x0319, 222 | keyTIME= 0x031A, 223 | keyERR= 0x031B, 224 | keyERL= 0x031C, 225 | keyCVI= 0x031D, 226 | keyCVS= 0x031E, 227 | keyCVD= 0x031F, 228 | keyCVL= 0x0320, 229 | keyMIN= 0x0321, 230 | keyMAX= 0x0322, 231 | keyCINT= 0x0323, 232 | keyFIX= 0x0324, 233 | keyXMOUSE= 0x0325, 234 | keyYMOUSE= 0x0326, 235 | keyXPOS= 0x0327, 236 | keyYPOS= 0x0328, 237 | keyPEEK16= 0x0329, 238 | keyPEEK32= 0x032A, 239 | keyRINSTR= 0x032B, 240 | keyFIND_FIRST_OF= 0x032C, 241 | keyFIND_LAST_OF= 0x032D, 242 | keyFIND_FIRST_NOT_OF= 0x032E, 243 | keyFIND_LAST_NOT_OF= 0x032F, 244 | keySINH= 0x0330, 245 | keyCOSH= 0x0331, 246 | keyTANH= 0x0332, 247 | keyASINH= 0x0333, 248 | keyACOSH= 0x0334, 249 | keyATANH= 0x0335, 250 | keyATAN2= 0x0336, 251 | keyTEST= 0x0337, 252 | keyTESTR= 0x0338, 253 | keyPOS= 0x0339, 254 | keyVPOS= 0x033A, 255 | keyLOF= 0x033B, 256 | keyFREEFILE= 0x033C, 257 | keyINKEY= 0x033D, 258 | keyROUND= 0x033E, 259 | keyCVSMBF= 0x033F, 260 | keyCVDMBF= 0x0340, 261 | keyREGEXP_INSTR= 0x0341, 262 | keyALLOC_MEMORY= 0x0342, 263 | keyLOC= 0x0343, 264 | 265 | keyNOT= 0x0401, 266 | keyOR= 0x0402, 267 | keyAND= 0x0403, 268 | keyTAB= 0x0404, 269 | keySPC= 0x0405, 270 | keyAT= 0x0406, 271 | keyXOR= 0x0407, 272 | keyMOD= 0x0408, 273 | keyUSING= 0x0409, 274 | 275 | keyIDENTIFIER= 0x0601, // Not in program. 276 | keyNUMBER= 0x0602, // Not in program. 277 | keySTRING= 0x0603, // Not in program. 278 | keyDISTINCT= 0x0604, 279 | keyMINOREQUAL= 0x0605, 280 | keyGREATEREQUAL= 0x0606, 281 | keyINTEGER= 0x0607, // Not in program. 282 | keyEQUALMINOR= 0x0608, 283 | keyEQUALGREATER= 0x0609, 284 | keyGREATERMINOR= 0x060A, 285 | keyENDLINE= 0x06FF, // Not in program. 286 | 287 | keyMAX_CODE_USED= 0x06FF; 288 | 289 | 290 | inline bool iskey (unsigned char c) 291 | { 292 | // Por ahora. 293 | return c == '\x01' || c == '\x02' || c == '\x03' || 294 | c == '\x04' || c == '\x06'; 295 | } 296 | 297 | const BlChar INTEGER_PREFIX= '\x05'; 298 | 299 | void excludekeyword (const std::string & str); 300 | BlCode keyword (const std::string & str); 301 | std::string decodekeyword (BlCode s); 302 | 303 | #endif 304 | 305 | // Fin de keyword.h 306 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ************************* 3 | 4 | Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 5 | 2006, 2007 Free Software Foundation, Inc. 6 | 7 | This file is free documentation; the Free Software Foundation gives 8 | unlimited permission to copy, distribute and modify it. 9 | 10 | Basic Installation 11 | ================== 12 | 13 | Briefly, the shell commands `./configure; make; make install' should 14 | configure, build, and install this package. The following 15 | more-detailed instructions are generic; see the `README' file for 16 | instructions specific to this package. 17 | 18 | The `configure' shell script attempts to guess correct values for 19 | various system-dependent variables used during compilation. It uses 20 | those values to create a `Makefile' in each directory of the package. 21 | It may also create one or more `.h' files containing system-dependent 22 | definitions. Finally, it creates a shell script `config.status' that 23 | you can run in the future to recreate the current configuration, and a 24 | file `config.log' containing compiler output (useful mainly for 25 | debugging `configure'). 26 | 27 | It can also use an optional file (typically called `config.cache' 28 | and enabled with `--cache-file=config.cache' or simply `-C') that saves 29 | the results of its tests to speed up reconfiguring. Caching is 30 | disabled by default to prevent problems with accidental use of stale 31 | cache files. 32 | 33 | If you need to do unusual things to compile the package, please try 34 | to figure out how `configure' could check whether to do them, and mail 35 | diffs or instructions to the address given in the `README' so they can 36 | be considered for the next release. If you are using the cache, and at 37 | some point `config.cache' contains results you don't want to keep, you 38 | may remove or edit it. 39 | 40 | The file `configure.ac' (or `configure.in') is used to create 41 | `configure' by a program called `autoconf'. You need `configure.ac' if 42 | you want to change it or regenerate `configure' using a newer version 43 | of `autoconf'. 44 | 45 | The simplest way to compile this package is: 46 | 47 | 1. `cd' to the directory containing the package's source code and type 48 | `./configure' to configure the package for your system. 49 | 50 | Running `configure' might take a while. While running, it prints 51 | some messages telling which features it is checking for. 52 | 53 | 2. Type `make' to compile the package. 54 | 55 | 3. Optionally, type `make check' to run any self-tests that come with 56 | the package. 57 | 58 | 4. Type `make install' to install the programs and any data files and 59 | documentation. 60 | 61 | 5. You can remove the program binaries and object files from the 62 | source code directory by typing `make clean'. To also remove the 63 | files that `configure' created (so you can compile the package for 64 | a different kind of computer), type `make distclean'. There is 65 | also a `make maintainer-clean' target, but that is intended mainly 66 | for the package's developers. If you use it, you may have to get 67 | all sorts of other programs in order to regenerate files that came 68 | with the distribution. 69 | 70 | 6. Often, you can also type `make uninstall' to remove the installed 71 | files again. 72 | 73 | Compilers and Options 74 | ===================== 75 | 76 | Some systems require unusual options for compilation or linking that the 77 | `configure' script does not know about. Run `./configure --help' for 78 | details on some of the pertinent environment variables. 79 | 80 | You can give `configure' initial values for configuration parameters 81 | by setting variables in the command line or in the environment. Here 82 | is an example: 83 | 84 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix 85 | 86 | *Note Defining Variables::, for more details. 87 | 88 | Compiling For Multiple Architectures 89 | ==================================== 90 | 91 | You can compile the package for more than one kind of computer at the 92 | same time, by placing the object files for each architecture in their 93 | own directory. To do this, you can use GNU `make'. `cd' to the 94 | directory where you want the object files and executables to go and run 95 | the `configure' script. `configure' automatically checks for the 96 | source code in the directory that `configure' is in and in `..'. 97 | 98 | With a non-GNU `make', it is safer to compile the package for one 99 | architecture at a time in the source code directory. After you have 100 | installed the package for one architecture, use `make distclean' before 101 | reconfiguring for another architecture. 102 | 103 | Installation Names 104 | ================== 105 | 106 | By default, `make install' installs the package's commands under 107 | `/usr/local/bin', include files under `/usr/local/include', etc. You 108 | can specify an installation prefix other than `/usr/local' by giving 109 | `configure' the option `--prefix=PREFIX'. 110 | 111 | You can specify separate installation prefixes for 112 | architecture-specific files and architecture-independent files. If you 113 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses 114 | PREFIX as the prefix for installing programs and libraries. 115 | Documentation and other data files still use the regular prefix. 116 | 117 | In addition, if you use an unusual directory layout you can give 118 | options like `--bindir=DIR' to specify different values for particular 119 | kinds of files. Run `configure --help' for a list of the directories 120 | you can set and what kinds of files go in them. 121 | 122 | If the package supports it, you can cause programs to be installed 123 | with an extra prefix or suffix on their names by giving `configure' the 124 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. 125 | 126 | Optional Features 127 | ================= 128 | 129 | Some packages pay attention to `--enable-FEATURE' options to 130 | `configure', where FEATURE indicates an optional part of the package. 131 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE 132 | is something like `gnu-as' or `x' (for the X Window System). The 133 | `README' should mention any `--enable-' and `--with-' options that the 134 | package recognizes. 135 | 136 | For packages that use the X Window System, `configure' can usually 137 | find the X include and library files automatically, but if it doesn't, 138 | you can use the `configure' options `--x-includes=DIR' and 139 | `--x-libraries=DIR' to specify their locations. 140 | 141 | Specifying the System Type 142 | ========================== 143 | 144 | There may be some features `configure' cannot figure out automatically, 145 | but needs to determine by the type of machine the package will run on. 146 | Usually, assuming the package is built to be run on the _same_ 147 | architectures, `configure' can figure that out, but if it prints a 148 | message saying it cannot guess the machine type, give it the 149 | `--build=TYPE' option. TYPE can either be a short name for the system 150 | type, such as `sun4', or a canonical name which has the form: 151 | 152 | CPU-COMPANY-SYSTEM 153 | 154 | where SYSTEM can have one of these forms: 155 | 156 | OS KERNEL-OS 157 | 158 | See the file `config.sub' for the possible values of each field. If 159 | `config.sub' isn't included in this package, then this package doesn't 160 | need to know the machine type. 161 | 162 | If you are _building_ compiler tools for cross-compiling, you should 163 | use the option `--target=TYPE' to select the type of system they will 164 | produce code for. 165 | 166 | If you want to _use_ a cross compiler, that generates code for a 167 | platform different from the build platform, you should specify the 168 | "host" platform (i.e., that on which the generated programs will 169 | eventually be run) with `--host=TYPE'. 170 | 171 | Sharing Defaults 172 | ================ 173 | 174 | If you want to set default values for `configure' scripts to share, you 175 | can create a site shell script called `config.site' that gives default 176 | values for variables like `CC', `cache_file', and `prefix'. 177 | `configure' looks for `PREFIX/share/config.site' if it exists, then 178 | `PREFIX/etc/config.site' if it exists. Or, you can set the 179 | `CONFIG_SITE' environment variable to the location of the site script. 180 | A warning: not all `configure' scripts look for a site script. 181 | 182 | Defining Variables 183 | ================== 184 | 185 | Variables not defined in a site shell script can be set in the 186 | environment passed to `configure'. However, some packages may run 187 | configure again during the build, and the customized values of these 188 | variables may be lost. In order to avoid this problem, you should set 189 | them in the `configure' command line, using `VAR=value'. For example: 190 | 191 | ./configure CC=/usr/local2/bin/gcc 192 | 193 | causes the specified `gcc' to be used as the C compiler (unless it is 194 | overridden in the site shell script). 195 | 196 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to 197 | an Autoconf bug. Until the bug is fixed you can use this workaround: 198 | 199 | CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash 200 | 201 | `configure' Invocation 202 | ====================== 203 | 204 | `configure' recognizes the following options to control how it operates. 205 | 206 | `--help' 207 | `-h' 208 | Print a summary of the options to `configure', and exit. 209 | 210 | `--version' 211 | `-V' 212 | Print the version of Autoconf used to generate the `configure' 213 | script, and exit. 214 | 215 | `--cache-file=FILE' 216 | Enable the cache: use and save the results of the tests in FILE, 217 | traditionally `config.cache'. FILE defaults to `/dev/null' to 218 | disable caching. 219 | 220 | `--config-cache' 221 | `-C' 222 | Alias for `--cache-file=config.cache'. 223 | 224 | `--quiet' 225 | `--silent' 226 | `-q' 227 | Do not print messages saying which checks are being made. To 228 | suppress all normal output, redirect it to `/dev/null' (any error 229 | messages will still be shown). 230 | 231 | `--srcdir=DIR' 232 | Look for the package's source code in directory DIR. Usually 233 | `configure' can determine that directory automatically. 234 | 235 | `configure' also accepts some other, not widely useful, options. Run 236 | `configure --help' for more details. 237 | 238 | -------------------------------------------------------------------------------- /fileconsole.cpp: -------------------------------------------------------------------------------- 1 | // fileconsole.cpp 2 | // Revision 6-feb-2005 3 | 4 | #ifdef __BORLANDC__ 5 | #pragma warn -8022 6 | #endif 7 | 8 | #include "file.h" 9 | 10 | #include "blassic.h" 11 | #include "error.h" 12 | #include "cursor.h" 13 | #include "edit.h" 14 | #include "sysvar.h" 15 | #include "util.h" 16 | 17 | #include "trace.h" 18 | 19 | #include 20 | using std::cerr; 21 | using std::endl; 22 | #include 23 | #include 24 | 25 | #ifndef BLASSIC_USE_WINDOWS 26 | 27 | #include 28 | 29 | #else 30 | 31 | #include 32 | #undef max 33 | #undef min 34 | #ifdef HAVE_UNISTD_H 35 | #include 36 | #endif 37 | #if defined HAVE_IO_H || ! defined BLASSIC_CONFIG 38 | #include 39 | #endif 40 | 41 | #endif 42 | 43 | //*********************************************** 44 | // Auxiliary functions 45 | //*********************************************** 46 | 47 | namespace { 48 | 49 | class updateposchar { 50 | public: 51 | updateposchar (int & pos) : 52 | pos (pos) 53 | { } 54 | void operator () (const char c) 55 | { 56 | switch (c) 57 | { 58 | case '\r': 59 | case '\n': 60 | pos= 0; 61 | break; 62 | case '\b': 63 | if (pos > 0) 64 | --pos; 65 | break; 66 | case '\a': 67 | // Bell does not use space in screen. 68 | break; 69 | case '\t': 70 | pos= ( (pos / 8) + 1) * 8; 71 | break; 72 | default: 73 | ++pos; 74 | } 75 | } 76 | private: 77 | int & pos; 78 | }; 79 | 80 | void updatepos (int & pos, const std::string & str) 81 | { 82 | std::for_each (str.begin (), str.end (), updateposchar (pos) ); 83 | } 84 | 85 | } // namespace 86 | 87 | namespace blassic { 88 | 89 | namespace file { 90 | 91 | //*********************************************** 92 | // BlFileConsole 93 | //*********************************************** 94 | 95 | class BlFileConsole : public BlFile { 96 | public: 97 | //BlFileConsole (std::istream & nin, std::ostream & nout); 98 | BlFileConsole (); 99 | bool isfile () const { return false; } 100 | virtual bool eof (); 101 | virtual void flush (); 102 | virtual size_t getwidth () const; 103 | virtual void movecharforward (); 104 | virtual void movecharforward (size_t n); 105 | virtual void movecharback (); 106 | virtual void movecharback (size_t n); 107 | virtual void movecharup (); 108 | virtual void movecharup (size_t n); 109 | virtual void movechardown (); 110 | virtual void movechardown (size_t n); 111 | virtual void showcursor (); 112 | virtual void hidecursor (); 113 | virtual std::string getkey (); 114 | virtual std::string inkey (); 115 | void getline (std::string & str, bool endline= true); 116 | std::string read (size_t n); 117 | void tab (); 118 | void tab (size_t n); 119 | void gotoxy (int x, int y); 120 | virtual void setcolor (int color); 121 | virtual void setbackground (int color); 122 | virtual void cls (); 123 | int pos (); 124 | bool poll (); 125 | private: 126 | void outstring (const std::string & str); 127 | void outchar (char c); 128 | //void outnumber (BlNumber n); 129 | //void outinteger (BlInteger n); 130 | 131 | std::istream & in; 132 | std::ostream & out; 133 | bool ttyin, ttyout; 134 | #ifndef BLASSIC_USE_WINDOWS 135 | int xpos; 136 | #endif 137 | }; 138 | 139 | BlFile * newBlFileConsole () 140 | { 141 | return new BlFileConsole (); 142 | } 143 | 144 | //BlFileConsole::BlFileConsole (std::istream & nin, std::ostream & nout) : 145 | BlFileConsole::BlFileConsole () : 146 | BlFile (OpenMode (Input | Output) ), 147 | //in (nin), 148 | //out (nout), 149 | in (std::cin), 150 | out (std::cout), 151 | ttyin (isatty (0) ), 152 | ttyout (isatty (1) ) 153 | //#ifndef _Windows 154 | #ifndef BLASSIC_USE_WINDOWS 155 | , xpos (0) 156 | #endif 157 | { 158 | TRACEFUNC (tr, "BlFileConsole::BlFileConsole"); 159 | TRMESSAGE (tr, std::string ("ttyin ") + 160 | (ttyin ? "is" : "is not") + " a tty"); 161 | TRMESSAGE (tr, std::string ("ttyout ") + 162 | (ttyout ? "is" : "is not") + " a tty"); 163 | } 164 | 165 | bool BlFileConsole::eof () 166 | { 167 | if (! ttyin) 168 | { 169 | int c= in.get (); 170 | if (! in || c == EOF) 171 | return true; 172 | else 173 | { 174 | in.unget (); 175 | return false; 176 | } 177 | } 178 | else 179 | { 180 | return false; 181 | } 182 | } 183 | 184 | void BlFileConsole::flush () 185 | { 186 | out << std::flush; 187 | } 188 | 189 | size_t BlFileConsole::getwidth () const 190 | { 191 | return cursor::getwidth (); 192 | } 193 | 194 | void BlFileConsole::movecharforward () 195 | { 196 | cursor::movecharforward (); 197 | } 198 | 199 | void BlFileConsole::movecharforward (size_t n) 200 | { 201 | cursor::movecharforward (n); 202 | } 203 | 204 | void BlFileConsole::movecharback () 205 | { 206 | cursor::movecharback (); 207 | } 208 | 209 | void BlFileConsole::movecharback (size_t n) 210 | { 211 | cursor::movecharback (n); 212 | } 213 | 214 | void BlFileConsole::movecharup () 215 | { 216 | cursor::movecharup (); 217 | } 218 | 219 | void BlFileConsole::movecharup (size_t n) 220 | { 221 | cursor::movecharup (n); 222 | } 223 | 224 | void BlFileConsole::movechardown () 225 | { 226 | cursor::movechardown (); 227 | } 228 | 229 | void BlFileConsole::movechardown (size_t n) 230 | { 231 | cursor::movechardown (n); 232 | } 233 | 234 | void BlFileConsole::showcursor () 235 | { 236 | cursor::showcursor (); 237 | } 238 | 239 | void BlFileConsole::hidecursor () 240 | { 241 | cursor::hidecursor (); 242 | } 243 | 244 | std::string BlFileConsole::getkey () 245 | { 246 | //TRACEFUNC (tr, "BlFileConsole::getkey"); 247 | 248 | if (ttyin) 249 | { 250 | std::string str= cursor::getkey (); 251 | 252 | #ifdef BLASSIC_USE_WINDOWS 253 | 254 | if (str.size () == 1) 255 | { 256 | char c= str [0]; 257 | OemToCharBuff (& c, & c, 1); 258 | return std::string (1, c); 259 | } 260 | 261 | #endif 262 | 263 | return str; 264 | } 265 | else 266 | { 267 | int c= in.get (); 268 | if (! in || c == EOF) 269 | throw ErrPastEof; 270 | return std::string (1, static_cast (c) ); 271 | } 272 | } 273 | 274 | std::string BlFileConsole::inkey () 275 | { 276 | std::string str= cursor::inkey (); 277 | 278 | #ifdef BLASSIC_USE_WINDOWS 279 | 280 | if (ttyin && str.size () == 1) 281 | { 282 | char c= str [0]; 283 | OemToCharBuff (& c, & c, 1); 284 | return std::string (1, c); 285 | } 286 | 287 | #endif 288 | 289 | return str; 290 | } 291 | 292 | void BlFileConsole::getline (std::string & str, bool endline) 293 | { 294 | using blassic::edit::editline; 295 | 296 | TRACEFUNC (tr, "BlFileConsole::getline"); 297 | 298 | if (ttyin) 299 | { 300 | std::string auxstr; 301 | //int inicol= getcursorx (); 302 | int inicol= pos (); 303 | while (! editline (* this, auxstr, 0, inicol, endline) ) 304 | continue; 305 | swap (str, auxstr); 306 | } 307 | else 308 | { 309 | std::getline (in, str); 310 | if (! in) 311 | throw ErrPastEof; 312 | } 313 | 314 | if (fInterrupted) 315 | { 316 | in.clear (); 317 | str.erase (); 318 | return; 319 | } 320 | 321 | #ifdef BLASSIC_USE_WINDOWS 322 | 323 | if (ttyin) 324 | { 325 | size_t l= str.size (); 326 | util::auto_buffer aux (l); 327 | OemToCharBuff (str.data (), aux, l); 328 | str= std::string (aux, l); 329 | } 330 | 331 | #endif 332 | } 333 | 334 | std::string BlFileConsole::read (size_t n) 335 | { 336 | util::auto_buffer buf (n); 337 | in.read (buf, n); 338 | return std::string (buf, n); 339 | } 340 | 341 | void BlFileConsole::tab () 342 | { 343 | int zone= static_cast (sysvar::get16 (sysvar::Zone) ); 344 | if (zone == 0) 345 | { 346 | outchar ('\t'); 347 | return; 348 | } 349 | 350 | #if 0 351 | 352 | #ifdef BLASSIC_USE_WINDOWS 353 | 354 | int newpos= getcursorx (); 355 | 356 | #else 357 | 358 | int pos= xpos; 359 | 360 | #endif 361 | 362 | #else 363 | 364 | int newpos= pos (); 365 | 366 | #endif 367 | 368 | const int width= 80; // This may need another approach. 369 | if (newpos >= (width / zone) * zone) 370 | endline (); 371 | else 372 | { 373 | do 374 | { 375 | outchar (' '); 376 | ++newpos; 377 | } while (newpos % zone); 378 | } 379 | } 380 | 381 | void BlFileConsole::tab (size_t n) 382 | { 383 | int p= pos (); 384 | if (p > static_cast (n) ) 385 | { 386 | outchar ('\n'); 387 | p= pos (); 388 | } 389 | outstring (std::string (n - p, ' ') ); 390 | } 391 | 392 | void BlFileConsole::outstring (const std::string & str) 393 | { 394 | TRACEFUNC (tr, "BlFileConsole::outstring"); 395 | 396 | #ifdef BLASSIC_USE_WINDOWS 397 | 398 | if (ttyout) 399 | { 400 | size_t l= str.size (); 401 | util::auto_buffer aux (l + 1); 402 | CharToOemBuff (str.data (), aux, l); 403 | aux [l]= 0; 404 | out << aux; 405 | } 406 | else 407 | out << str; 408 | 409 | #else 410 | 411 | out << str; 412 | updatepos (xpos, str); 413 | 414 | #endif 415 | 416 | #ifndef NDEBUG 417 | out << std::flush; 418 | #endif 419 | 420 | if (! out) 421 | { 422 | out.clear (); 423 | //throw std::runtime_error ("Al diablo"); 424 | } 425 | } 426 | 427 | void BlFileConsole::outchar (char c) 428 | { 429 | #ifdef BLASSIC_USE_WINDOWS 430 | 431 | if (ttyout) 432 | CharToOemBuff (& c, & c, 1); 433 | 434 | #endif 435 | 436 | if (c == '\n') 437 | out << endl; 438 | else 439 | out << c; 440 | 441 | #ifndef BLASSIC_USE_WINDOWS 442 | 443 | updateposchar (xpos).operator () (c); 444 | 445 | #endif 446 | 447 | if (! out) 448 | { 449 | out.clear (); 450 | //throw std::runtime_error ("Al diablo"); 451 | } 452 | } 453 | 454 | #if 0 455 | 456 | void BlFileConsole::outnumber (BlNumber n) 457 | { 458 | #if 0 459 | if (graphics::ingraphicsmode () ) 460 | graphics::stringout (to_string (n) ); 461 | else 462 | #endif 463 | out << n; 464 | } 465 | 466 | void BlFileConsole::outinteger (BlInteger n) 467 | { 468 | #if 0 469 | if (graphics::ingraphicsmode () ) 470 | graphics::stringout (to_string (n) ); 471 | else 472 | #endif 473 | out << n; 474 | } 475 | 476 | #endif 477 | 478 | void BlFileConsole::gotoxy (int x, int y) 479 | { 480 | cursor::gotoxy (x, y); 481 | 482 | #ifndef BLASSIC_USE_WINDOWS 483 | 484 | xpos= x; 485 | 486 | #endif 487 | } 488 | 489 | void BlFileConsole::setcolor (int color) 490 | { 491 | cursor::textcolor (color); 492 | } 493 | 494 | void BlFileConsole::setbackground (int color) 495 | { 496 | cursor::textbackground (color); 497 | } 498 | 499 | void BlFileConsole::cls () 500 | { 501 | cursor::cls (); 502 | 503 | #ifndef BLASSIC_USE_WINDOWS 504 | 505 | xpos= 0; 506 | 507 | #endif 508 | } 509 | 510 | int BlFileConsole::pos () 511 | { 512 | #ifdef BLASSIC_USE_WINDOWS 513 | 514 | return cursor::getcursorx (); 515 | 516 | #else 517 | 518 | return xpos; 519 | 520 | #endif 521 | } 522 | 523 | bool BlFileConsole::poll () 524 | { 525 | return cursor::pollin (); 526 | } 527 | 528 | } // namespace file 529 | 530 | } // namespace blassic 531 | 532 | // End of fileconsole.cpp 533 | --------------------------------------------------------------------------------