You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
MBC/mbc4.linux.cc

20628 lines
602 KiB

// *********************************************************************
// Created with MBC (V) 4.0-Beta4 (2022/07/26)Ported to OSX by Armando Rivera
// Ported from BCX32 BASIC To C/C++ Translator (V) 5.12
// BCX (c) 1999 - 2018 by Kevin Diggins
// LinuxBC (c) 2009 by Mike Henning
// MBC (c) 2009 - 2018 by Armando Rivera
// *********************************************************************
// Translated for compiling with the g++ Compiler
// g++ -Wformat -D_FORTIFY_SOURCE=2 -Wno-write-strings $FILE$.cc -ldl -o $FILE$
// *********************************************************************
#include <stdbool.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <setjmp.h>
#include <time.h>
#include <stdarg.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
#include <dlfcn.h>
// ***************************************************
// Compiler Defines
// ***************************************************
#define C_EXPORT extern "C"
#define C_IMPORT extern "C"
#ifndef stat
#define lstat stat
#endif
#ifndef _fcloseall
#define _fcloseall _fcloseall
#endif
#ifndef HWND
#define HWND GHWND
#endif
#ifndef MAX_PATH
#define MAX_PATH 2048
#endif
#ifndef CALLBACK
#define CALLBACK
#endif
typedef unsigned int HINSTANCE;
typedef void* LPVOID;
typedef char* PCHAR;
typedef unsigned char BYTE;
typedef unsigned int UINT;
typedef unsigned char UCHAR;
typedef unsigned char* PUCHAR;
typedef unsigned long ULONG;
typedef unsigned long* ULONG_PTR;
typedef unsigned long DWORD;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
#define BOOL bool
// ***************************************************
typedef long (*CPP_FARPROC)(char *);
// *************************************************
// User Defined Constants
// *************************************************
#define Version "4.0-Beta4 (2022/07/26)"
#define __BCX__ 1
#define vt_VarMin 2
#define vt_VarMax vt_VARIANT
#define fprintf ReDirectFPrint
#define MaxElements 128
#define MaxTypes 512
#define MaxLocalVars 512
#define MaxGlobalVars 4096
#define MaxLib 64
#define c_SglQt 39
#define c_DblQt 34
#define c_LPar 40
#define c_RPar 41
#define c_Komma 44
#define c_LtBkt 91
#define c_RtBkt 93
#define BCX_STR_RUNTIME "Runtime Functions"
#define BCX_STR_MAIN_PROG "Main Program"
#define BCX_STR_SYS_VARS "System Variables"
#define BCX_STR_STD_MACROS "Standard Macros"
#define BCX_STR_STD_PROTOS "Standard Prototypes"
#define BCX_STR_USR_PROCS "User Subs and Functions"
#define BCX_STR_USR_VARS "User Global Variables"
#define BCX_STR_USR_PROTOS "User Prototypes"
#define BCX_STR_USR_CONST "User Defined Constants"
#define BCX_STR_USR_TYPES "User Defined Types, Classes (CPP Mode), And Unions"
#define FUNCTIONPARSE_CLASS struct _FUNCTIONPARSE*
#define VarTypes "%$#!@¦"
#define ARGTYPE_CLASS struct _ARGTYPE*
#define PROTOSTORE_CLASS struct _PROTOSTORE*
#define ELEMENT_CLASS struct _ELEMENT*
#define USERTYPEDEFS_CLASS struct _USERTYPEDEFS*
#define VARINFO_CLASS struct _VARINFO*
#define VARCODE_CLASS struct _VARCODE*
#define iMatchLft(A,B) iMatch (A ,B ,0)
#define iMatchWrd(A,B) iMatch (A ,B ,1)
#define iMatchRgt(A,B) iMatch (A ,B ,2)
// *************************************************
// User's GLOBAL ENUM blocks
// *************************************************
enum
{
vt_UNKNOWN,
vt_STRLIT,
vt_INTEGER,
vt_SINGLE,
vt_DOUBLE,
vt_LDOUBLE,
VT_LLONG,
vt_STRVAR,
vt_DECFUNC,
vt_NUMBER,
vt_FILEPTR,
vt_UDT,
vt_STRUCT,
vt_UNION,
vt_BOOL,
vt_CHAR,
vt_LPSTRPTR,
vt_PCHAR,
vt_CHARPTR,
vt_VOID,
vt_LONG,
vt_DWORD,
vt_FARPROC,
vt_LPBYTE,
vt_LRESULT,
vt_BYTE,
vt_SHORT,
vt_USHORT,
vt_UINT,
vt_ULONG,
vt_HWND,
vt_HDC,
vt_COLORREF,
vt_HANDLE,
vt_HINSTANCE,
vt_WNDCLASSEX,
vt_HFONT,
vt_VARIANT
};
enum
{
mt_ProcessSetCommand,
mt_FuncSubDecC_Dec,
mt_FuncSubDecC_Dec2,
mt_Opts,
mt_Opts2,
mt_Opts3,
mt_OverLoad,
mt_OverLoad2,
mt_FuncSubx1,
mt_FuncSubx2
};
// *************************************************
// User Defined Types, Classes (CPP Mode), And Unions
// *************************************************
typedef struct _functionParse
{
int NumArgs;
int CommaPos[128];
}functionParse, *LPFUNCTIONPARSE;
typedef struct _ARGTYPE
{
char Arg[2048];
int ArgType;
}ARGTYPE, *LPARGTYPE;
typedef struct _ProtoStore
{
char Prototype[2048];
char Condition[512];
int CondLevel;
}ProtoStore, *LPPROTOSTORE;
typedef struct _Element
{
int ElementType;
int ElementID;
int ElementDynaPtr;
char ElementName[64];
}Element, *LPELEMENT;
typedef struct _UserTypeDefs
{
int TypeofDef;
int EleCnt;
struct _Element Elements[MaxElements];
char VarName[64];
}UserTypeDefs, *LPUSERTYPEDEFS;
typedef struct _VarInfo
{
int VarLine;
int VarType;
int VarDef;
int VarPntr;
int VarSF;
int VarExtn;
int VarCondLevel;
int VarEmitFlag;
int VarConstant;
char VarName[64];
char VarDim[128];
char VarModule[300];
char VarCondDef[128];
}VarInfo, *LPVARINFO;
typedef struct _VARCODE
{
int VarNo;
int Method;
int IsPtrFlag;
char Header[2048];
char Proto[2048];
char Functype[2048];
char StaticOut[2048];
char Token[2048];
char AsToken[2048];
}VARCODE, *LPVARCODE;
// *************************************************
// System Variables
// *************************************************
char TAB [2]={9,0}; // Horz Tab
char LF [2]={10,0}; // Line Feed
char ESC [2]={27,0}; // Escape
char SPC [2]={32,0}; // Space
char DQ [2]={34,0}; // Double-Quote
char DDQ [3]={34,34,0}; // Double-Double-Quote
char CRLF[3]={13,10,0}; // Carr Rtn & Line Feed
char *AR_fgets_retval;
// *************************************************
// User Global Variables
// *************************************************
static PCHAR *G_argv;
static int G_argc;
static int NoRT;
static int ByrefCnt;
static char CurLine[65535];
static int gLinesWritten;
static int LoopLocalCnt;
static int GlobalVarCnt;
static int TypeDefsCnt;
static int LocalVarCnt;
static int LocalDynArrCount;
static int LocalDynaCnt;
static int GlobalDynaCnt;
static int ModuleNdx;
static int FPtrNdx;
static int SplitCnt;
static int SplitCur;
static char SrcTmp[65535];
static int StartNdx;
static int ExitNdx;
static VARCODE VarCode;
static int UmQt;
static char LD_FLAGS[65535];
static char Accelerator[65535];
static char CallType[65535];
static int CaseFlag;
static char CaseVar[65535];
static char Cmd[65535];
static char Compiler[65535];
static char CmdLineConst[65535];
static char CmdLineFileOut[65535];
static int CurrentFuncType;
static char DimType[65535];
static int DllCnt;
static int LoadLibsCnt;
static float Elapsed;
static int EndOfProgram;
static int EntryCnt;
static int ErrFile;
static char szFile[65535];
static char Filnam[65535];
static int ForceMainToFunc;
static char Funcname[65535];
static char Handl[65535];
static int HFileCnt;
static char HFile[65535];
static int InConditional;
static char InIfDef[65535];
static int Indent;
static int InFunc;
static int InMain;
static int IsCallBack;
static int TurboSize;
static int UseCProto;
static int InTypeDef;
static int IsAuto;
static int NoTypeDeclare;
static int IsDim;
static int IsExported;
static int IsRegister;
static int IsStatic;
static int IsStdFunc;
static int IsLocal;
static int IsRaw;
static int IsApple;
static int KillCFile;
static char Keyword1[65535];
static int LastCmd;
static int LinesRead;
static char Linker[65535];
static char Lookup[65535];
static int MakeDLL;
static int Ndx;
static int NoMain;
static int NoDllMain;
static int OkayToSend;
static char Op[65535];
static int OptionBase;
static char OutfileClone[65535];
static int PassOne;
static int ProtoCnt;
static int Pusher;
static int Quiet;
static int ReDirect;
static FILE *SaveOutfileNum;
static char Scoot[65535];
static int ShowStatus;
static int SrcCnt;
static int SrcFlag;
static int TrcFlag;
static int TestForBcxIni;
static char FileIn[65535];
static char FileOut[65535];
static char FileErr[65535];
static char T[65535];
static int Test;
static int Statements;
static int TestState;
static char Tipe[65535];
static int TranslateSlash;
static int UseCpp;
static int UseFlag;
static int InNameSpace;
static int Use_Virtual;
static char vproc[65535];
static int UseStdCall;
static int UseLCaseTbl;
static char Var[65535];
static int XitCount;
static char Z[65535];
static char ConstLastDef[65535];
static int Use_AnsiToWide;
static int Use_Asc;
static int Use_AppExeName;
static int Use_AppExePath;
static int Use_Boolstr;
static int Use_Bor;
static int Use_Band;
static int Use_Bnot;
static int Use_BcxSplitPath;
static int Use_Bin;
static int Use_Bin2dec;
static int Use_Osx;
static int Use_Cvd;
static int Use_Cvld;
static int Use_Cvi;
static int Use_Cvl;
static int Use_Cvs;
static int Use_Chr;
static int Use_Cdbl;
static int Use_Cldbl;
static int Use_Csng;
static int Use_Clear;
static int Use_Cbool;
static int Use_Cint;
static int Use_Clng;
static int Use_Cls;
static int Use_Color;
static int Use_Command;
static int Use_ContainedIn;
static int Use_Console;
static int Use_CopyFile;
static int Use_Static;
static int Use_Crlf;
static int Use_Curdir;
static int Use_Del;
static int Use_Download;
static int Use_Dynacall;
static int Use_DynamicA;
static int Use_Embed;
static int Use_Enclose;
static int Use_Environ;
static int Use_EnumFile;
static int Use_Eof;
static int Use_Exist;
static int Use_ExitCode;
static int Use_Extract;
static int Use_LoadFile;
static int Use_FillArray;
static int Use_Findfirst;
static int Use_Findnext;
static int Use_FindInType;
static int Use_Fint;
static int Use_Fix;
static int Use_FileLocked;
static int Use_Frac;
static int Use_Fracl;
static int Use_Freefile;
static int Use_Get;
static int Use_GetCh;
static int Use_GenFree;
static int Use_Gosub;
static int Use_Gtk;
static int Use_Glib;
static int Use_Hex;
static int Use_Hex2Dec;
static int Use_Iif;
static int Use_Imod;
static int Use_Inkey;
static int Use_InkeyD;
static int Use_Ins;
static int Use_Instr;
static int Use_Inchr;
static int Use_Isptr;
static int Use_iReplace;
static int Use_IRemove;
static int Use_Instrrev;
static int Use_Join;
static int Use_Keypress;
static int Use_Lcase;
static int Use_Ldouble;
static int Use_Left;
static int Use_Like;
static int Use_Lineinput;
static int Use_Loc;
static int Use_Locate;
static int Use_Lof;
static int Use_Lpad;
static int Use_Ltrim;
static int Use_Mcase;
static int Use_Mid;
static int Use_Midstr;
static int Use_Mkd;
static int Use_Mkld;
static int Use_Mki;
static int Use_Mkl;
static int Use_Mks;
static int Use_Min;
static int Use_Max;
static int Use_Now;
static int Use_Numqsortdint;
static int Use_Numqsortaint;
static int Use_Numqsortdfloat;
static int Use_Numqsortafloat;
static int Use_Numqsortddouble;
static int Use_Numqsortadouble;
static int Use_Idxqsort;
static int Use_IdxqsortSt;
static int Use_PtrqsortSt;
static int Use_Oct;
static int Use_Overloaded;
static int Use_OSVersion;
static int Use_Pause;
static int Use_PeekStr;
static int Use_Put;
static int Use_QBColor;
static int Use_Randomize;
static int Use_Rec;
static int Use_RecCount;
static int Use_Remain;
static int Use_Remove;
static int Use_Repeat;
static int Use_Replace;
static int Use_Reverse;
static int Use_Right;
static int Use_Rpad;
static int Use_Rnd;
static int Use_Exp;
static int Use_Retain;
static int Use_Round;
static int Use_Rtrim;
static int Use_Run;
static int Use_Scan;
static int Use_Inputbuffer;
static int Use_SearchPath;
static int Use_StrUpLow;
static int Use_Shell;
static int Use_Sgn;
static int Use_SingleFile;
static int Use_Space;
static int Use_Split;
static int Use_DSplit;
static int Use_StartupCode;
static int Use_Stristr;
static int Use_StrStr;
static int Use_Str;
static int Use_Strl;
static int Use_Str_Cmp;
static int Use_Strim;
static int Use_String;
static int Use_Strptr;
static int Use_Strqsorta;
static int Use_Strqsortd;
static int Use_Strtoken;
static int Use_DynStrqsorta;
static int Use_DynStrqsortd;
static int Use_Swap;
static int Use_Sysdir;
static int Use_SysStr;
static int Use_sziif;
static int Use_Tally;
static int Use_Tempdir;
static int Use_TempFileName;
static int Use_Threads;
static int Use_Time;
static int Use_Timer;
static int Use_Trim;
static int Use_Turbo;
static int Use_Ubound;
static int Use_Ucase;
static int Use_Using;
static int Use_VChr;
static int Use_Verify;
static int Use_Val;
static int Use_Vall;
static int Use_WideToAnsi;
static int Use_Wx;
static int Use_WxC;
static int Use_Ctor;
static int Use_Instat;
static int Use_Socket;
static int Use_IOS;
static int Use_RegEx;
static int Use_BEL;
static int Use_BS;
static int Use_CR;
static int Use_DDQ;
static int Use_DQ;
static int Use_EOF;
static int Use_ESC;
static int Use_FF;
static int Use_LF;
static int Use_NUL;
static int Use_SPC;
static int Use_TAB;
static int Use_VT;
static char prcFile[65535];
static char udtFile[65535];
static char datFile[65535];
static char cstFile[65535];
static char ovrFile[65535];
static char hdrFile[65535];
static char setFile[65535];
static char enuFile[65535];
static char *szTmp;
static char *Src;
static char *AbortSrc;
static char *WarnMsg;
static char *RmLibs;
static FILE *SourceFile;
static FILE *FP2;
static FILE *FP3;
static FILE *FP4;
static FILE *FP5;
static FILE *FP6;
static FILE *FP7;
static FILE *FP8;
static FILE *FP9;
static FILE *FP11;
static FILE *Outfile;
static FILE *FP1;
static int DoCountLines;
static FILE *FP10;
static FILE *ResIn;
static FILE *ResOut;
static FILE *UserResIn;
static FILE *fpErr;
static FILE *fpHFile;
static FILE *FP68;
static FILE *fpdef;
static int SFPOINTER;
static int WithCnt;
static char ByrefVars[1024][65535];
static int LoopLocalVar[256];
static int BaseTypeDefsCnt[16];
static char Modules[256][65535];
static int ModuleLineNos[256];
static FILE *FPtr[256];
static char Stk[4096][65535];
static ProtoStore ProtoType[1024];
static char SrcStk[128][65535];
static char SplitStk[128][65535];
static char CaseStk[256][65535];
static int CaseElseFlag[256];
static char Entry[256][65535];
static char Xit[256][65535];
static char LocalDynArrName[256][65535];
static char GlobalDynaStr[256][65535];
static char DynaStr[256][65535];
static char StartSub[32][65535];
static char ExitSub[32][65535];
static char Library[MaxLib][65535];
static int GlobalVarHash[MaxGlobalVars];
static VarInfo GlobalVars[MaxGlobalVars];
static VarInfo LocalVars[MaxLocalVars];
static UserTypeDefs TypeDefs[MaxTypes];
static char DllDecl[800][512];
static char Loadlibs[128][512];
static char HFiles[128][65535];
static char TypeName[16][65535];
static char WithVar[8][65535];
// *************************************************
// Standard Macros
// *************************************************
#define FDRV 2
#define FPATH 4
#define FNAME 8
#define FEXT 16
#define BAND &
#define BOR |
#define imod(a,b)((a)%(b))
#define VAL(a)(double)atof(a)
// *************************************************
// Standard Prototypes
// *************************************************
int str_cmp(char*, char*);
int EoF (FILE*);
void cls(void);
void locate (int,int,int=1,int=12);
void midstr (char*, int, int, char *);
char* BCX_TmpStr(size_t);
char* sziif (bool,char*,char*);
char* TempFileName (char*,char*);
char* AppExePath (void);
char* AppExeName (void);
char* lcase (char*);
char* ucase (char*);
char* mid (char*, int, int=-1);
char* ltrim (char*,char=32);
char* rtrim (char*,char=32);
char* trim (char*);
char* strim (char*);
char* left (char*,int);
char* right (char*,int);
char* rpad (char*,int,int=32);
char* lpad (char*,int,int=32);
char* stringx (int,int);
char* extract (char*,char*);
char* remain (char*,char*);
char* command (int=-1);
char* replace (char*,char*,char*);
char* iReplace (char*,char*,char*);
void Shell (char *);
char* space (int a);
char* str (double);
char* curdir (void);
char* tempdir (void);
char* Environ (char*);
char* _strupr_(char *);
char* _strlwr_(char *);
char* BcxSplitPath (char *, int);
void _splitpath_(const char* path, char* drv, char* dir, char* name, char* ext);
char* StrToken (char*,char*,int);
char* RemoveStr (char*,char*);
char* IRemoveStr (char*,char*);
char* join (int, ... );
char* enc (char*, int=0, int=0);
char* chr(int,int=0,int=0,int=0,int=0,int=0,int=0,int=0,int=0,int=0);
char* vchr (int,...);
int InstrRev (char*,char*,int=0,int=0);
int instr_b(char*,char*,int=0,int=0);
char *MakeLCaseTbl(void);
char *_stristr_(char*,char*);
char *_strstr_(char*,char*);
int inchr (char*,char*);
int tally (char*,char*,int=0);
BOOL Exist (char*);
char* ins (char *S, int i, char *a);
char* del (char*,int,int);
DWORD lof (char*);
double Round (double,int);
float rnd (void);
double _MIN_ (double,double);
double _MAX_ (double,double);
int containedin(char * ,char **,int=0);
// *************************************************
// User Prototypes
// *************************************************
int main (int, PCHAR* );
void EmitCmdLineConst (void);
void EmitCompilerDefines (void);
void MakeFreeGlobals (void);
void ProcessSetCommand (int);
int Directives (void);
int SubVarType (int);
char * PrintWriteFormat (int);
void EmitInputCode (void);
void EmitFileInputCode (void);
void AddFuncs (void);
int CheckLocal (char *, int* );
int CheckGlobal (char *, int* );
int CheckType (char *);
void ExportInternalConst (void);
int RestrictedWords (char *);
int DataType (char *);
void CloseAll (void);
char * Clean (char *);
void RemoveAll (char* ,char* ,int=0);
void Warning (char* ,int=0);
PCHAR GetVarTypeName (int);
int HashNumber (char *);
void AddLibrary (char *);
void RemoveLibrary (char *);
void EmitLibs (void);
void AddGlobal (char* ,int,int,char* ,int,int,int,int,int=0);
void AddLocal (char* ,int,int,char* ,int,int,int,int=0);
int IsNumber (char *);
int IsNumberEx (char *);
void StripTabs (void);
void PushFileIO (void);
void PopFileIO (void);
int Inset (char *, char *);
void CheckParQuotes (void);
void ClearIfThenStacks (void);
int IsQuoted (char *);
void PostProcess (void);
void XParse (char *);
void TokenSubstitutions (void);
void JoinStrings (int, int);
void Transforms (void);
void Parse (char *);
void FuncSubDecs1 (char *);
void RemEmptyTokens (void);
void FuncSubDecs2 (char *, int);
void FuncSubDecs3 (VARCODE* );
void AddTypeDefs (char *, int);
int DefsID (char *);
void GetTypeInfo (char *, int* , int* , int* );
void AddTypedefElement (int, int, char *, char *, int);
char * GetElement (int, int* , int* , int);
int GetElementInfo (int* , int* , char *);
void HandleNonsense (void);
void ValidVar (char *);
void PointerFix (void);
void DimDynaString (char *, int, int);
int SubFuncTest (void);
int DimSubFunc (int);
void Emit (void);
void Abort (char *);
void BumpDown (void);
void BumpUp (void);
int BraceCount (char *);
char* BracketHandler (char *, int);
void Push (char *);
void Pop (char *);
void EmitEpilog (void);
void EmitProlog (void);
void DeclareVariables (void);
int GetNumArgs (int,int* =NULL);
void GetVarCode (VARCODE* );
void AddProtos (void);
void RunTimeFunctions (void);
int JoinLines (char *);
void StripCode (char *);
void ProcSingleLineIf (int* );
int SplitLines (char *);
int iMatch (char *, char *, int);
int iMatchNQ (char *, char *);
int SpecialCaseHandler (char *);
void FastLexer (char* ,char* ,char* ,int=1);
void InsertTokens (int, int, ...);
void EmitExportDef (char *);
char * GetArg (int, functionParse* );
int SepFuncArgs (int, functionParse* , int);
PCHAR MakeDecProto (functionParse* );
void AsmUnknownStructs (int);
void EmitIfCond (char *);
void PrintGlobal (int, int, char *, char *, char *, char *);
void ReDirectFPrint (FILE*, char *, ...);
int IsReservedWord (char *);
int GetAsPos (void);
void FreeGlobals (void);
// *************************************************
// User Global Initialized Arrays
// *************************************************
// *************************************************
// User GLOBAL SET Statements
// *************************************************
static char* VarTypeLookup[]=
{
"int","int","char *","double","float","FILE *","long double"
};
static char VarConst[2][8]=
{
"",
"const "
};
static char VarStorage[6][18]=
{
"static ",
"extern ",
"",
"static volatile ",
"extern volatile ",
"volatile "
};
static char* ReservedWord[]=
{
"IF",
"ELSEIF",
"THEN",
"ELSE",
"AND",
"OR",
"NOT",
"BOR",
"BAND",
"XOR",
""
};
// *******************************************************************************
// Developer Guidelines
// *******************************************************************************
// Code should be written in BCX Basic. If it can not be written in BCX Basic for
// some reason or results in code that seems too inefficient then this may be a
// cue that a new Basic function is needed.
// * All KEYWORDS should be capitalized
// * Use two space indentation
// * Use spaces not tabs
// * Record all notes in reverse chronological order
// * And most importantly....Have fun!
// ******************************************************************************************
// This section is used to communicate to-do 's, changes, ideas, suggestions, etc.
// ******************************************************************************************
// -------------------------------------------
// 2022-07-26 Armando Rivera
// After a LONG time away....
// * Changed max size of szTmp$, Src$, and AbortSrc$ (65535)to avoid potential buffer overflows
// * Changed max size of WarnMsg$ (65536) to avoid potential buffer overflow
// * Removed the "register" decorator from EOF function to comply with C++17 standard
// * The above addressed warnings thrown by C++17, which is the standard on modern Linux.
// * Removed cdecl/stdcall from "Declare Function" (dynamic linking), since cdecl is the standard on *nix systems
// -------------------------------------------
// 2018-12-12 Armando Rivera
// * Changed BcxRegEx function to REGMATCH
// * Changed BcxRegEx keyword to REGMATCH
// * Added $MODULE as alias to $INCLUDE to support external modules. ** MUST BE AT TOP OF MAIN SOURCE FILE **
// * Added $LDFLAGS directive to support external modules
// -------------------------------------------
// -------------------------------------------
// 2016-02-15 Armando Rivera
// -------------------------------------------
// * Changed default string size to 65K from
// 2k, which was limiting.
// * Updated output of PRINT command, eliminating
// leading spaces from numbers.
// -------------------------------------------
// 2015-07-03 Armando Rivera
// -------------------------------------------
// * Changed $OSX flag to use Cocoa instead of Carbon in MacOS
// This is in preparation of the new custom libcocoa library
// that I'm currently creating that will allow mbc
// to create 64bit GUI applications in OSX
// -------------------------------------------
// 2013-06-26 Armando Rivera
// -------------------------------------------
// * Added BcxRegex keyword, based on Posix Regex in Libc
// * Broke up main source file into files containing Runtime, Declarations, etc.
// * Added BYTE type
//
// -------------------------------------------
// 2013-06-17 Armando Rivera
// -------------------------------------------
// * Tweaked HEX$ so that it will emit 2-digit hex numbers
// * Added PUCHAR (unsigned char*) typedef
// -------------------------------------------
// 2011-03-11 Armando Rivera
// -------------------------------------------
// * Added Wayne's suggestion to support Reference Variables as return types.
//
// -------------------------------------------
// 2011-03-10 Armando Rivera
// -------------------------------------------
// * Ported $PROJECT directive from ConsoleBC. This doesn't emit the RTL yet, but it's a start.
// It's the first step towards re-writing the RT code to leverage CPP/WX.
//
// * Fixed bug where BCX_TmpStr sometimes wasn't emitted when returning a string from a function
//
// * Added Named Enum support. Syntax:
// myenum AS ENUM
// …
// END ENUM
//
// This required moving the Enum emit code to before the User Prototype emit code
// to allow passing the named enum to user defined functions.
//
// -------------------------------------------
// 2011-01-23 Armando Rivera
// -------------------------------------------
// * Initial Beta1 Release
//
// * Fixed bug in INPUT statement to remove trailing newlines (James Fuller)
//
// * Removed COLOR statements to avoid terminal output issues with redirected
// translator output (James Fuller)
//
// * Added CONST keyword when declaring variables (Global, Local, and as Function/Sub parameters)
// At the moment, this is experimental (meaning I haven't fully tested it) but it seems to work
//
// * Added PRIVATE keyword for CPP classes
// -------------------------------------------
// 2010/12/21 Armando Rivera
// -------------------------------------------
// * Cleaned up code emission so that unneeded defines/global vars are not emitted
//
// * Added new $IOS directive, which is MAC ONLY, to compile source for iDevices (iPhone/iTouch/AppleTV2)
// At this point in time, running binaries built this way requires a jailbroken iDevice.
// This is experimental, and for console apps only for now.
// A simple console example is in the Examples/IOS folder
// -------------------------------------------
// 2010/12/11 Armando Rivera
// -------------------------------------------
// * Add new Socket keywords: BcxSocket, BcxSocketSend, BcxSocketRead, and BcxSocketClose
// See the BcxSocket.bas demo in the Examples/Socket folder for info.
//
// * Added kbhit() , which doesn't exist outside of Windows
// This is a custom sub which emulates what kbhit() does
//
// * Changed the conditional emission of term.h to only be emitted when
// Use_Keypress is TRUE (InKey)
//
// -------------------------------------------
// 2010/12/01 Armando Rivera
// -------------------------------------------
// * Changed wxApp emission to use BCXPLITHPATH$, per James Fuller's suggestion.
//
// * Added support for Abstract Classes (gcc doesn't have the INTERFACE keyword)
//
// Example:
// Class MyAbstractClass
// public
//
// virtual sub Proc1() = 0
// Virtual sub Proc2()=0
// virtual function Proc3(a$,b$) as integer = 0
//
// End Class
// -------------------------------------------
// 2010/11/30 Armando Rivera
// -------------------------------------------
// * Removed $CLASS/$ENDCLASS $NAMESPACE/$ENDNAMESPACE
// Using either will emit a message stating that they have been replaced.
//
// * Addded NAMESPACE / END NAMESPACE
// This allows creating methods within the NAMESPACE like so:
//
// $CPP
// $NOMAIN
// $EXECON
// '==============================================================================
// NAMESPACE Dlg_01
// Sub DoIt()
// Print "Dlg_01"
// End Sub
//
// Function GetString$(A$) as string
// function = "The String you Passed Was: " + enc$(A$)
// end function
// END NAMESPACE
// '==============================================================================
// Function main(argc as INTEGER, argv as PCHAR ptr) as INTEGER
// Print "James"
// Dlg_01::DoIt()
// print Dlg_01::GetString$("Hello, World!")
// End Function
//
// * If using $WX, the #define for Clear() will not be emitted due to conflict
// with Classes that have that method defined
//
// * Made the inclusion of "term.h" conditional based on whether $WX/$WXC
// is used. "term.h" is required for the implementation of
// the PAUSE keyword in CONSOLE apps.
//
// -------------------------------------------
// 2010/11/25 Armando Rivera
// -------------------------------------------
// * Changed code so that in $CPP mode, the case of the emitted
// .cpp filename is preserved (James Fuller bug report)
//
// -------------------------------------------
// 2010/11/24 Armando Rivera
// -------------------------------------------
// * Minor change in StripCode() to correct
// possible overflow issue under 64bit Linux (James Fuller bug report)
//
// * Added $WXC Directive to support WX Console-Based Apps
// Using this switch, neither a wxApp or the IMPLEMENT_APP() macro are
// auto added to the translated source (James Fuller request)
// -------------------------------------------
// 2010/11/20 Armando Rivera
// -------------------------------------------
// * Changed $DLL directive so that it would generate *nix Shared Libraries.
// * Added $DLL support to $EXECON
// * Added required flags to LD_FLAGS$ for creating *nix Shared Libraries
// Example:
// $dll
// $execon
//
// function printdemo() export
// print "This was called from a Dynamic Library"
// end function
//
// Note that this is currently only useful for creating shared libraries
// for **OTHER** languages; it won't work with MBC created apps because of
// duplicate naming conflicts.
//
// -------------------------------------------
// 2010/11/18 Armando Rivera
// -------------------------------------------
// * Removed "-Os" compiler optimization flag from $EXECON for fastest tranlator compliation
// during Alpha testing stage.
//
// This will be re-added when translator is not longer in Alpha status
//
// * Added USE_CTOR global as flag for supporting Constructor/Destructor syntax
//
// * Added "USING" keyword for CONSTRUCTOR/DESTRUCTOR methods. It is used like this:
//
// CONSTRUCTOR MainWin::MainWin(title as wxString, winStyle as long) USING wxFrame( 0, -1, title, wxPoint(50,50), wxSize(490,296), winStyle )
//
// Which will emit:
//
// MainWin::MainWin (wxString title, long winStyle)
// : wxFrame( 0, -1, title, wxPoint(50,50), wxSize(490,296), winStyle )
// {
//
// * Added code to extract and emit derived class methods
//
// -------------------------------------------
// 2010/11/17 Armando Rivera
// -------------------------------------------
// * Added new CLASS / END CLASS / PUBLIC / PROTECTED / CONSTRUCTOR / DESTRUCTOR keywords.
// These additions flesh out Basic-Like C++ CLASS support, superceding $CLASS/$ENDCLASS,
// and now allows syntax like the following:
//
// $CPP
// $NOMAIN
// $execon
//
// class MyClass
//
// protected
// first as string
// secnd$
// third%
//
// public
// type ATest
// a as PCHAR
// b as long
// c as single
// d as float
// end type
//
// Constructor MyClass(a$, b)
// Destructor MyClass()
// end class
//
// FUNCTION main(argc as INTEGER, argv as PCHAR ptr) as INTEGER
// RAW theClass as MyClass PTR
//
// theClass = new MyClass("Hello", 12)
//
// print (char*)theClass->ATest.a
// print theClass->ATest.b
// END FUNCTION
//
// Constructor MyClass::MyClass(a$,b)
// ATest.a = a$
// ATest.b = b
// END Constructor
// '
// Destructor MyClass::~MyClass()
//
// END Destructor
//
// -------------------------------------------
// 2010/11/12 Armando Rivera
// -------------------------------------------
// * Added code that (mostly) eliminates the need for a trailing ";" in $class/$endclass
//
// * Added code to allow the use of "SUB" in $class/$endclass. It just substitutes "void" for "sub"
// at this point.
//
// * Fixed "THIS" keyword code so that it emits a lowercase "this". Linux/OSX aren't affected
// by this breaking COM statements. :-P Thanks to JCFULLER for the tip!
//
// * For $CPP mode, added typedefs for std::string (CSTRING) and std::fstream (CFILE)
// These are direct replacements for STRING and FILE, and allows the full use of each
// C++ object/class.
//
// So instead of "dim mystring as string", for example, you would do "dim mystring as CSTRING".
// You would then have access to all of std::string's methods like .replace, .substr, .compare, etc.
//
// I'm considering doing the same with the other toolkit directives ($OSX, $GTK, etc) but we'll see...
//
// * Added "inherits" in $CPP mode so that subclassing can be done like so:
//
// $class MyClass inherits AnotherClass
//
// * For $WX mode, added code to automatically emit the required derived wxApp class.
// Note that it will be named the same as your sourcefile (minus the extension), and you MUST provide
// a "FUNCTION ::OnInit() as bool" for it:
//
// FUNCTION TestApp::OnInit() as bool
// <initialize app here>
// END FUNCTION
//
// * For $WX mode, made "$NOMAIN" the default, so no need to pass that directive
//
// * Colorized some of the compiler output text. Just because I can.
//
// * Back-ported Wayne's changes to "WITH" to allow the use of "->" syntax
//
// * TODO:
// Finish off the $class/$endclass code to allow full basic syntax for method and variable
// declarations.
//
// Remove ALL remaining WIN32 related code and ifdefs.
// No need for that stuff under Linux/OSX, the Windows version of BCX can handle all
// of the Windows stuff one might need.
//
// Other stuff I can't remember right now…..
// -------------------------------------------
// 2010/03/31 Armando Rivera
// Beginning with this version of the console compiler,
// the goal is to have a 100% unified code-base, because
// I'm fracking tired of trying to maintain separate builds
// for different Operating Systems.
// -------------------------------------------
//
// * Added $OSX, $GTK¸$GLIB and $WX Directives
// (Use_Osx, Use_Wx, Use_Gtk, Use_Glib and LD_FLAGS$ Globals added)
//
// $OSX will automatically enable Carbon GUI support, and if $EXECON is invoked
// will also build a Universal Binary with 32bit and 64bit support
//
// $GTK will automatically enable GTK/GLIB support, and if $EXECON is invoked
// will build the executable linking in libgtk and it's support libraries.
//
// $GLIB will automatically enable >GLIB ONLY< support, and if $EXECON is invoked
// will build the executable linking in libglib and it's support libraries.
//
// $WX will automatically enable wxWidgets with $CPP set to "TRUE", and if $EXECON
// is invoked will build the executable linking in libwx and it's support libraries
//
// This is, in part, in preparation for moving the GTK support from the core of the
// LinuxBC translator to an external library which will be linked in as required. This
// will GREATLY simplify maintenence of the translator core once the lib is ready.
//
// * Changed alls instances of byte* to UCHAR* in SWAP() Function
//
// * Added internal return values for PUT/GET to get rid of ALL compiler warnings.
//
// * Updated runtime functions calling PUT()/GET()/fread()/fwrite so that they
// will not trigger compiler warnings
//
// * Reworked the way functions declared using C_DECLARE with the LIB and ALIAS keywords
// are emitted. This is so that you can dynamically load functions from a shared
// library at runtime via dlopen/dlsym.
//
// The syntax is:
// C_DECLARE FUNCTION <YOUR FUNCTION NAME> LIB <shared library> ALIAS <quoted name of actual function (<parameters>) AS <return type>
//
// For example:
// C_DECLARE FUNCTION b64encode LIB "libglib-2.0.so" ALIAS "g_base64_encode" (txt AS char*, length AS integer) AS string
// C_DECLARE FUNCTION g_base64_decode LIB "libglib-2.0.so" ALIAS "g_base64_decode" (txt AS char*, length AS INTEGER PTR) AS string
//
// NOTE that the ALIAS is the actual name of the function you want to call from the shared library.
// This is so you avoid redeclaration errors if you attempt to link to a library (libm is a good example)
// that is already compile-time linked with g++.
//
// NOTE 2: There is currently no checking whether the function was loaded without error. It is on the TODO list.
//
// * Changed compiler invocation to include -Wformat and -D_FORTIFY_SOURCE=2 (Ubuntu Standard)
//
// * Fixed User Include File handling in order to support mixed case filenames
//
// * Updated the CURDIR$, TEMPDIR$, AND SHELL code to eliminate warnings emitted when compiling on
// a system that has "_FORTIFY_SOURCE=2" enabled by default in GCC/G++ (Ubuntu)
//
// * Fixed a potential overflow problem with LINE INPUT that would also cause G++ to emit
// warnings as above.
//
// *Re-coded the $RESOURCE directive and the GETRESOURCE$ function to allow
// linking of Resources under Linux/Unix. Using $RESOURCE generates a #define
// allowing you to reference the embedded resource using an arbitrary IDENTIFIER.
//
// For example:
//
// DIRECTIVE FILE IDENTIFIER
// -------------------------------
// $RESOURCE "file.txt" "myres"
//
//
// Note that you reference the resource using the identifier you passed as the
// SECOND parameter to the $RESOURCE directive, minus the quotes.
//
// "file.txt" above can be any arbitrary file on one's system
//
// At the moment, the resource is returned as a string with the GETRESOURCE$ function.
// *****************************************************************************************************
// ** YOU WILL HAVE TO ENSURE THAT A BUFFER WITH ENOUGH SPACE TO HOLD THE RESOURCE HAS BEEN ALLOCATED **
// *****************************************************************************************************
// To aid in this, a constant is automatically created with the size of the resource. It will have the
// name you specified as the second parameter to $RESOURCE, with _SIZE appended.
// Using the example above, the constant would be defined as: myres_SIZE
//
//
// You should be able to manually cast the reference *itself* to what you require, since it is
// merely a pointer to the location of the resource itself.
//
// The resource will be converted to an object file, named using the filename provided with ".o" apppended.
// "file.txt" will be converted to "file.txt.o" in the above example, which can then be linked
// to the final executable via $EXECON "file.txt.o" or $EXEGUI "file.txt.o"
//
// * Tweaked $GUI directive and GUI keyword so that one can use the directive without
// having all of the support for BCX_* form objects automatically added to one's app.
//
// This is usefull when using GtkBuilder or Glade to build the user interface.
//
// -------------------------------------------
// 2010-01-17 Armando Rivera
// -------------------------------------------
// modified the $CLASS/$ENDCLASS directives to allow creation and inheritance of C++ Classes
//
// modified the Function/Sub prototype emitter so that it would not emit prototypes
// for C++ Class Methods, which are supposed to be prototyped within the Class itself
//
// made the inclusion of <term.h> conditional based on whether UseCPP is true/false
// it will not be included if UseCpp is "true" because some C++ toolkits (wxWidgets)
// throw a "redefined" error when it's included
//
// -------------------------------------------
// 2010-01-15 Armando Rivera
// -------------------------------------------
// per wmhalsdorf's recommendation, modified SplitLines and Emit procs to support
// C++ Method syntax (CLASSNAME::METHOD) [see Yahoo group Message #40282]
//
// -------------------------------------------
// 2010-01-10 Armando Rivera
// -------------------------------------------
// changed $CPP directive to output lowercase filenames
//
// -------------------------------------------
// 2009-10-18 Armando Rivera
// -------------------------------------------
// added Carbon.h as a default include, to support Carbon/CoreFoundation calls
// added Carbon framework to $execon section
// removed TRUE and FALSE defines, which are now provided by Carbon.h
// changed Handle$ to Handl$ to resolve conflict with Carbon.h
//
// -------------------------------------------
// 2009-10-13 Armando Rivera
// -------------------------------------------
// added typedef for "byte" type (typedef unsigned char byte;)
//
// *************************************************
// Runtime Functions
// *************************************************
char *BCX_TmpStr (size_t Bites)
{
static int StrCnt;
static char *StrFunc[512];
StrCnt=((StrCnt+1) &511);
#if defined BCX_MAX_VAR_SIZE
if(Bites*sizeof(char)>BCX_MAX_VAR_SIZE)
{
printf("Buffer Overflow caught in BCX_TmpStr - requested space of %d EXCEEDS %d\n",(int)(Bites*sizeof(char)),BCX_MAX_VAR_SIZE);
abort();
}
#endif
StrFunc[StrCnt]=(char*)realloc(StrFunc[StrCnt],Bites + 128);
return (char*)memset(StrFunc[StrCnt],0,Bites+128);
}
int str_cmp (char *a, char *b)
{
int counter=0;
for(;;)
{
if((a[counter]^b[counter]))
{
if((UINT) a[counter]>= (UINT) b[counter])
return 1;
return -1;
}
if(!a[counter]) return 0;
counter++;
}
}
int EoF (FILE* stream)
{
int c, status = ((c = fgetc(stream)) == EOF);
ungetc(c,stream);
return status;
}
char *left (char *S, int length)
{
int tmplen = strlen(S);
if(length<1) return BCX_TmpStr(1);
if(length<tmplen) tmplen=length;
char *strtmp = BCX_TmpStr(tmplen);
return (char*)memcpy(strtmp,S,tmplen);
}
char *right (char *S, int length)
{
int tmplen = strlen(S);
char *BCX_RetStr = BCX_TmpStr(tmplen);
tmplen -= length;
if (tmplen<0) tmplen = 0;
return strcpy(BCX_RetStr, &S[tmplen]);
}
char *rpad (char *a, int L, int c)
{
char *strtmp;
int s = strlen(a);
if((L-s)<1) return a;
strtmp=BCX_TmpStr(L);
strcpy(strtmp,a);
memset(&strtmp[s],c,(L-s));
return strtmp;
}
char *lpad (char *a, int L, int c)
{
char *strtmp;
L=L-strlen(a);
if(L<1) return a;
strtmp = BCX_TmpStr(L);
memset(strtmp,c,L);
return strcat(strtmp,a);
}
char *mid (char *S, int start, int length)
{
char *strtmp;
int tmplen = strlen(S);
if(start>tmplen||start<1) return BCX_TmpStr(1);
if (length<0 || length>(tmplen-start)+1)
length = (tmplen-start)+1;
strtmp = BCX_TmpStr(length);
return (char*)memcpy(strtmp,&S[start-1],length);
}
char *trim (char *S)
{
while(*S==32 || *S==9 || *S==10 || *S==11 || *S==13)
S++;
int i = strlen(S);
while( i>0 && (S[i-1]==32 || S[i-1]==9 || S[i-1]==10
|| S[i-1]==11 || S[i-1]==13))
i--;
char *strtmp=BCX_TmpStr(i);
return (char*)memcpy(strtmp,S,i);
}
char *ltrim (char *S, char c)
{
if(S[0]==0) return S;
while((*S==32 || *S==c) && *S !=0) S++;
char *strtmp = BCX_TmpStr(strlen(S));
return strcpy(strtmp,S);
}
char *rtrim (char *S,char c)
{
if(S[0]==0) return S;
int i = strlen(S);
while(i>0 && (S[i-1]==c || S[i-1]==32))
i--;
char *strtmp = BCX_TmpStr(i);
return (char*)memcpy(strtmp,S,i);
}
char *strim (char *src)
{
char *strtmp = BCX_TmpStr(strlen(src));
char *dst = strtmp;
while (isspace((unsigned char)*src)) src++;
do
{
while (*src && !isspace((unsigned char)*src)) *dst++ = *src++;
if (*src)
{
*dst++ = *src++;
while (isspace((unsigned char)*src)) src++;
}
} while (*src);
if (isspace((unsigned char)*(--dst))) *dst = 0;
return strtmp;
}
char *command (int nArg)
{
int i = 0;
char *retstr=BCX_TmpStr(1);
if(nArg < i) // return entire commandline
{
retstr = BCX_TmpStr(G_argc * 2048);
for(i=1; i < G_argc; i++)
{
strcat(retstr, G_argv[i]);
strcat(retstr, SPC);
}
}
else if(nArg < G_argc)
{
retstr = BCX_TmpStr(strlen(G_argv[nArg]) + 1);
strcpy(retstr, G_argv[nArg]);
}
return retstr;
}
char *extract (char *mane, char *match)
{
char *a;
char *strtmp = BCX_TmpStr(strlen(mane));
if(*match!=0)
{
a=_strstr_(mane,match);
if(a) return (char*)memcpy(strtmp,mane,a-mane);
}
return strcpy(strtmp,mane);
}
char *remain (char *mane, char *mat)
{
char *p = strstr(mane,mat);
if(p)
{
p+=(strlen(mat));
return p;
}
return mane;
}
char *replace (char *src, char *pat, char *rep)
{
size_t patsz, repsz, tmpsz, delta;
char *strtmp, *p, *q, *r;
if (!pat || !*pat)
{
strtmp = BCX_TmpStr(strlen(src));
if (!strtmp) return NULL;
return strcpy(strtmp, src);
}
repsz = strlen(rep);
patsz = strlen(pat);
for (tmpsz=0, p=src; (q=_strstr_(p,pat))!=0; p=q+patsz)
tmpsz += (size_t) (q - p) + repsz;
tmpsz += strlen(p);
strtmp = BCX_TmpStr(tmpsz);
if (!strtmp) return NULL;
for (r=strtmp,p=src; (q=_strstr_(p,pat))!=0;p=q+patsz)
{
delta = (size_t) (q-p);
memcpy(r,p,delta); r += delta;
strcpy(r,rep); r += repsz;
}
strcpy(r,p);
return strtmp;
}
char *ucase (char *S)
{
char *strtmp = BCX_TmpStr(strlen(S));
return _strupr_(strcpy(strtmp,S));
}
char *lcase (char *S)
{
char *strtmp = BCX_TmpStr(strlen(S));
return _strlwr_(strcpy(strtmp,S));
}
char *RemoveStr (char *a, char *b)
{
char *strtmp, *p, *d;
int tmplen;
strtmp = d = BCX_TmpStr(strlen(a));
if(!b || !*b) return strcpy(strtmp,a);
p=_strstr_(a,b); tmplen = strlen(b);
while(p)
{
memcpy(d,a,p-a);
d+= (p-a);
a=p+tmplen;
p=_strstr_(a,b);
}
strcpy(d,a);
return strtmp;
}
char *IRemoveStr (char *a, char *b)
{
char *strtmp, *p, *d;
int tmplen;
strtmp = d = BCX_TmpStr(strlen(a));
if(!b || !*b) return strcpy(strtmp,a);
p=_stristr_(a,b); tmplen = strlen(b);
while(p)
{
memcpy(d,a,p-a);
d+= (p-a);
a=p+tmplen;
p=_stristr_(a,b);
}
strcpy(d,a);
return strtmp;
}
char *ins (char *S, int i, char *a)
{
int j = strlen(S);
if(i<1 || i>j+1) return S;
char *strtmp = BCX_TmpStr(j + strlen(a));
memcpy(strtmp,S,--i);
strcpy(&strtmp[i],a);
return strcat(strtmp,&S[i]);
}
char *del (char *S, int i, int j)
{
int ln = strlen(S);
if(i<1 || i>ln) return S;
char *strtmp = BCX_TmpStr(ln);
memcpy(strtmp,S,--i);
return strcat(strtmp,&S[i+j]);
}
char *str (double d)
{
char *strtmp = BCX_TmpStr(16);
sprintf(strtmp,"% .15G",d);
return strtmp;
}
char *curdir (void)
{
char *strtmp = BCX_TmpStr(2048);
char *res=getcwd(strtmp, 1024);
return strtmp;
}
char *tempdir (void)
{
char *strtmp = BCX_TmpStr(2048);
if(!Exist("/tmp/mbc.compiler")) {
mkdir ("/tmp/mbc.compiler",0755);
}
strcpy(strtmp,"/tmp/mbc.compiler");
return strtmp;
}
char *stringx (int count, int a)
{
if(count<1) return BCX_TmpStr(1);
char *strtmp = BCX_TmpStr(count);
return (char*)memset(strtmp,a,count);
}
void Shell (char *cmd)
{
int res=system(cmd);
}
char *space (int count)
{
if(count<1) return BCX_TmpStr(1);
char *strtmp = BCX_TmpStr(count);
return (char*)memset(strtmp,32,count);
}
char *enc (char *A, int L, int R)
{
char *BCX_RetStr = BCX_TmpStr(strlen(A)+3);
if(L==0) L=34;
if(R==0) R=L;
sprintf(BCX_RetStr,"%c%s%c%s",L,A,R,"");
return BCX_RetStr;
}
char *chr (int a,int b,int c,int d,int e,int f,int g,int h,int i,int j)
{
char *strtmp = BCX_TmpStr(11);
strtmp[0] = a;
strtmp[1] = b;
strtmp[2] = c;
strtmp[3] = d;
strtmp[4] = e;
strtmp[5] = f;
strtmp[6] = g;
strtmp[7] = h;
strtmp[8] = i;
strtmp[9] = j;
strtmp[10] = 0;
return strtmp;
}
char *vchr(int charcount, ...)
{
int c = 0, i = charcount;
char *s_ = BCX_TmpStr(charcount + 1);
va_list marker;
s_[i] = 0;
va_start(marker, charcount);
while(i-- > 0) s_[c++] = va_arg(marker,int);
va_end(marker);
return s_;
}
char * join(int n, ...)
{
int i = n, tmplen = 0;
char *strtmp, *s_;
va_list marker;
va_start(marker, n); // Initialize variable arguments
while(i-- > 0)
{
s_ = va_arg(marker, char *);
if(s_) tmplen += strlen(s_);
}
strtmp = BCX_TmpStr(tmplen);
va_end(marker); // Reset variable arguments
i = n;
va_start(marker, n); // Initialize variable arguments
while(i-- > 0)
{
s_ = va_arg(marker, char *);
if(s_) strcat(strtmp, s_);
}
va_end(marker); // Reset variable arguments
return strtmp;
}
char* Environ(char *S)
{
char *strtmp, *tmp;
tmp = getenv(S);
if(tmp != NULL) {
strtmp = BCX_TmpStr(strlen(tmp)+1);
return strcpy(strtmp, tmp);
}
return BCX_TmpStr(1);
}
char *AppExePath (void)
{
char fullpath[MAX_PATH];
int length;
length = readlink("/proc/self/exe", fullpath, MAX_PATH);
if(length < 1) return BCX_TmpStr(1);
fullpath[length] = 0;
return BcxSplitPath(fullpath, FDRV|FPATH);
}
char *AppExeName (void)
{
return BcxSplitPath(G_argv[0], FNAME|FEXT);
}
char * TempFileName (char *dr, char *prefix)
{
static unsigned int count;
char *f, *tmpstr = BCX_TmpStr(MAX_PATH);
int i, length;
if(!count) srand(time(0));
if(dr) strcpy(tmpstr, dr);
length = strlen(tmpstr);
if(length && (tmpstr[length-1] != '\\' && tmpstr[length-1] != '/'))
tmpstr[length++] = '/';
if(prefix) strcpy(&tmpstr[length], prefix);
f = &tmpstr[strlen(tmpstr)];
do {
count++;
for(i=0; i<5; i+=1)
{
do {
f[i]=(char)(rnd()*122);
}while((f[i]<65)||(f[i]>90&&f[i]<97));
}
snprintf(&f[5],3,"%x", count);
} while (Exist(tmpstr));
return tmpstr;
}
int InstrRev (char *s, char *p, int os, int sens)
{
int sl, pl, ox;
int (*cmp)(const char *, const char *, size_t );
if (!s || !p) return 0;
sl = strlen(s); pl = strlen(p);
if (os > sl || sl == 0 || pl == 0 || (ox = sl - pl) < 0)
return 0;
if (os <= 0)
os = ox ;
else if(os >= pl)
os = os - pl ;
else
return 0;
cmp = (sens ? strncasecmp : strncmp);
do { if (cmp(s + os , p, pl) == 0)
return os+1;
} while (os--);
return 0;
}
int instr_b(char* mane,char* match,int offset,int sensflag)
{
char *s;
if (!mane || !match || ! *match || offset>(int)strlen(mane)) return 0;
if (sensflag)
s = _stristr_(offset>0 ? mane+offset-1 : mane,match);
else
s = _strstr_(offset>0 ? mane+offset-1 : mane,match);
return s ? (int)(s-mane)+1 : 0;
}
char *MakeLCaseTbl (void)
{
static char tbl[256];
if(!tbl['a'])
{
int i; for (i=0; i < 256; i++)
tbl[i] = (char)(int)tolower(i);
}
return tbl;
}
char *_stristr_(char *String, char *Pattern)
{
int mi=-1;
char *LowCase = MakeLCaseTbl();
while(Pattern[++mi])
{
if(String[mi]==0) return 0;
if(LowCase[(unsigned char)String[mi]]!=LowCase[(unsigned char)Pattern[mi]])
{ String++; mi=-1; }
}
return String;
}
char *_strstr_(char *String, char *Pattern)
{
int mi=-1;
while(Pattern[++mi])
{
if(String[mi]==0) return 0;
if(String[mi]!=Pattern[mi])
{ String++; mi=-1; }
}
return String;
}
int inchr (char *A, char *B)
{
char* C=A;
while(*C)
{
if(*C==*B) return C-A+1;
C++;
}
return 0;
}
double Round (double n, int d)
{
return (floor((n)*pow(10.0,(d))+0.5)/pow(10.0,(d)));
}
bool Exist (char *szFilePath)
{
int retstat;
struct stat sb;
retstat = stat(szFilePath, &sb);
if(retstat != -1)
return TRUE;
return FALSE;
}
int tally (char *szLine, char *szChar, int sensflag)
{
if(!*szChar) return 0;
int mlen = strlen(szChar);
int iCount = 0;
char *p = (sensflag == 0 ? _strstr_(szLine, szChar) : _stristr_(szLine, szChar));
while (p)
{
iCount++;
p+=mlen;
p = (sensflag == 0 ? _strstr_(p, szChar) : _stristr_(p, szChar));
}
return iCount;
}
float rnd (void)
{
return (float)rand()/RAND_MAX;
}
double _MAX_ (double a, double b)
{
if(a>b)
return a;
return b;
}
double _MIN_ (double a, double b)
{
if(a<b)
return a;
return b;
}
void locate (int row,int col,int show,int shape)
{
printf("%c%s%u%s%u%s",27,"[",row,";",col,"H");
// find cursor size/shape function!
}
void cls (void)
{
printf("%s%s%s%s",ESC,"[2J",ESC,"[H");
}
void midstr (char *src, int st, int length, char *rep)
{
int srclen = strlen(src);
if(st>srclen++ || st<1) return;
int replen = strlen(rep);
if(replen < length || length==-1) length=replen;
if((st+length) > srclen) length=srclen-st;
memcpy(&src[st-1],rep,length);
}
DWORD lof (char *FileName)
{
int retstat;
struct stat sb;
retstat = stat(FileName, &sb);
if(retstat != -1)
return sb.st_size;
return 0;
}
char * sziif (bool i, char *a, char *b)
{
if(i) return a;
return b;
}
char *BcxSplitPath (char *FPath, int mask)
{
if(!FPath) return BCX_TmpStr(1);
char *BCX_RetStr=BCX_TmpStr(strlen(FPath));
char tmp[MAX_PATH*4];
_splitpath_(FPath,tmp,&tmp[MAX_PATH],&tmp[MAX_PATH*2],&tmp[MAX_PATH*3]);
if(mask & FDRV) strcat(BCX_RetStr,tmp);
if(mask & FPATH)strcat(BCX_RetStr,&tmp[MAX_PATH]);
if(mask & FNAME)strcat(BCX_RetStr,&tmp[MAX_PATH*2]);
if(mask & FEXT) strcat(BCX_RetStr,&tmp[MAX_PATH*3]);
return BCX_RetStr;
}
void _splitpath_(const char* path, char* drv, char* dir, char* name, char* ext)
{
const char* pend; /* end of processed string */
const char* p; /* search pointer */
const char* s; /* copy pointer */
/* extract drive name */
if (path[0] && path[1]==':') {
if (drv) {
*drv++ = *path++;
*drv++ = *path++;
*drv = 0;
}
} else if (drv)
*drv = 0;
/* search for end of string or stream separator */
for(pend=path; *pend && *pend!=':'; )
pend++;
/* search for begin of file extension */
for(p=pend; p > path && *--p != '\\' && *p!='/'; )
if (*p == '.') {
pend = p;
break;
}
if (ext)
{
s=pend;
do{ *ext++ = *s; } while(*s++);
}
/* search for end of directory name */
for(p=pend; p > path; )
if (*--p == '\\' || *p == '/') {
p++;
break;
}
if (name) {
for(s=p; s<pend; )
*name++ = *s++;
*name = 0;
}
if (dir) {
for(s=path; s<p; )
*dir++ = *s++;
*dir = 0;
}
}
char *_strupr_(char *string)
{
char *s;
if (string)
{
for(s = string; *s; ++s)
*s = toupper(*s);
}
return string;
}
char *_strlwr_(char *string)
{
char *s;
if (string)
{
for (s = string; *s; ++s)
*s = tolower(*s);
}
return string;
}
char * StrToken (char *Source, char *TokenChar, int n)
{
char *BCX_RetStr={0};
char *RetVal;
char *Copy;
int Posn=0;
int Find=0;
int LenSrc=strlen(Source);
RetVal=(char*)calloc(LenSrc+1,1);
Copy=Source;
if(tally(Source,TokenChar)==0)
{
BCX_RetStr=BCX_TmpStr(1);
if(RetVal)free(RetVal);
return BCX_RetStr;
}
if(n==1)
{
BCX_RetStr=BCX_TmpStr(LenSrc);
strcpy(BCX_RetStr,(char*)extract(Source,TokenChar));
if(RetVal)free(RetVal);
return BCX_RetStr;
}
if(n>tally(Source,TokenChar)+1)
{
BCX_RetStr=BCX_TmpStr(1);
if(RetVal)free(RetVal);
return BCX_RetStr;
}
while(*Copy)
{
if(*Copy==TokenChar[0]) Find++;
if(Find==n) break;
Copy++;
Posn++;
}
if(n==tally(Source,TokenChar)+1)
{
Posn=LenSrc;
Copy=Source+Posn;
while(*Copy&&Source[Posn]!=TokenChar[0])
{
Posn--;
Copy--;
}
}
strcpy(RetVal,(char*)mid(Source,1,Posn));
strcpy(RetVal,(char*)mid(RetVal,InstrRev(RetVal,TokenChar)));
BCX_RetStr=BCX_TmpStr(LenSrc);
strcpy(BCX_RetStr,(char*)RemoveStr(RetVal,TokenChar));
if(RetVal)free(RetVal);
return BCX_RetStr;
}
char *iReplace (char *src, char *pat, char *rep)
{
size_t patsz, repsz, tmpsz, delta;
char *strtmp, *p, *q, *r;
if (!pat || !*pat)
{
strtmp = BCX_TmpStr(strlen(src));
if (!strtmp) return NULL;
return strcpy(strtmp, src);
}
repsz = strlen(rep);
patsz = strlen(pat);
for (tmpsz=0, p=src;(q=_stristr_(p,pat))!=0; p=q+patsz)
tmpsz += (size_t) (q - p) + repsz;
tmpsz += strlen(p);
strtmp = BCX_TmpStr(tmpsz);
if (!strtmp) return NULL;
for (r=strtmp,p=src;(q=_stristr_(p,pat))!=0;p=q+patsz)
{
delta = (size_t) (q-p);
memcpy(r,p,delta); r += delta;
strcpy(r,rep); r += repsz;
}
strcpy(r,p);
return strtmp;
}
int containedin(char * Token,char **Contain ,int c)
{
int i=0;
while(Contain[i][0])
{
if(0 == ((c == 0 || c == 2) ? strcmp(Contain[i],Token) : strcasecmp(Contain[i],Token)))
{
return ((c < 2) ? 0 : i);
}
i++;
}
return -1;
}
// ************************************
// User Subs and Functions
// ************************************
int main (int argc, PCHAR* argv)
{
G_argc=argc;
G_argv=argv;
szTmp=(char*)calloc(256+65535,1);
Src=(char*)calloc(256+65535,1);
AbortSrc=(char*)calloc(256+65535,1);
WarnMsg=(char*)calloc(256+65535+1,1);
RmLibs=(char*)calloc(256+32767,1);
static int bitz;
memset(&bitz,0,sizeof(bitz));
ProtoCnt=0;
TranslateSlash=TRUE;
OkayToSend=TRUE;
Use_SingleFile=TRUE;
Use_StartupCode=FALSE;
StartNdx=0;
Use_ExitCode=FALSE;
ExitNdx=0;
*HFile=0;
*CmdLineFileOut=0;
*RmLibs=0;
InMain=TRUE;
TestState=FALSE;
*CmdLineConst=0;
bitz=sizeof(long)*8;
if(command(-1)[0]==0)
{
#if defined (__APPLE__)
printf("%s\n","MBC4: Ported to Mac OSX by Armando Rivera (c) 2009-2018");
#else
printf("%s\n","MBC4: Based on Linux BCX by Mike Henning (c) 2009");
printf("%s%s\n","(c) 2009-2018 Armando Rivera with additional code (c) 2009 John Jacques",LF);
#endif
printf("%s%s%s","Version ",Version," Compiled with ");
// FP3
#if defined __BCPLUSPLUS__// OUTFILE
printf("%s\n","Borland C++");
#elif defined __BORLANDC__
printf("%s\n","Borland C");
#elif defined __POCC__
printf("%s\n","Pelles C");
#elif defined __GNUG__
printf("%s\n","GNU G++");
#else
printf("%s\n","Unknown");
#endif // Main
if(bitz==64)
{
printf("\n");
printf("%s\n","********************");
printf("%s\n","** 64 BIT VERSION **");
printf("%s%s\n","********************",LF);
}
printf("%s%s%s\n"," Usage: ",AppExeName()," infile [.bas] [options]");
printf("%s\n"," [-c] Generate C++ Compatible code");
printf("%s%s%s\n"," [-d] DEFINE a constant ... ex. ",AppExeName()," MyFile -D:MyConst[=SomeValue]");
printf("%s\n"," [-e] Write ERRORS to BCX.ERR file");
printf("%s%s%s\n"," [-f] Output FILENAME... ex. ",AppExeName()," MyFile -f:/MyFiles/MyFile.c");
printf("%s\n"," [-k] KILL the generated BCX generated 'C' file");
printf("%s\n"," [-o] OUTPUT a copy of the generated C file to STDOUT");
printf("%s\n"," [-q] QUIET - No output to screen during translation");
printf("%s\n"," [-s] Show STATUS of translation by line number");
printf("%s\n"," [-w] Enable WARNINGS during translation");
printf("%s%s%s\n"," [-t] TURBO Mode ON w/optional size ... ex. ",AppExeName()," MyFile -t[:1024]");
printf("%s\n"," [-u] Turn UNICODE Support ON");
FreeGlobals();
fflush(stdout);
exit(0);
}
Quiet=FALSE;
{int i;
for(i=2; i<=argc-1; i+=1)
{
if(instr_b(lcase(argv[i]),"-f"))
{
strcpy(CmdLineFileOut,mid(argv[i],4));
}
if(instr_b(lcase(argv[i]),"-d"))
{
strcpy(CmdLineConst, join(3,CmdLineConst,mid(argv[i],4),chr(1)));
}
if(str_cmp(lcase(argv[i]),"-c")==0)
{
UseCpp=TRUE;
}
if(str_cmp(lcase(argv[i]),"-e")==0)
{
ErrFile=TRUE;
}
if(str_cmp(lcase(argv[i]),"-q")==0)
{
Quiet=TRUE;
}
if(str_cmp(lcase(argv[i]),"-k")==0)
{
KillCFile=TRUE;
}
if(str_cmp(lcase(argv[i]),"-o")==0)
{
ReDirect=TRUE;
}
if(str_cmp(lcase(argv[i]),"-s")==0)
{
ShowStatus=TRUE;
}
if(str_cmp(lcase(argv[i]),"-w")==0)
{
TestState=TRUE;
}
if(instr_b(lcase(argv[i]),"-t"))
{
Use_Turbo=TRUE;
TurboSize=VAL(mid(argv[i],4));
if(TurboSize!=0)
{
if((TurboSize&(TurboSize-1))!=0)
{
TurboSize=512;
Warning("Invalid $Turbo size - defaulting to 512");
}
}
else
{
TurboSize=512;
}
}
}
}
if(ShowStatus)
{
cls();
}
if(!Quiet)
{
cls();
printf("%s%s\n","MBC Version ",Version);
#if defined (__APPLE__)
IsApple=TRUE;
printf("%s%s\n","MBC4: Ported to Mac OSX by Armando Rivera (c) 2009-2018",LF);
#else
printf("%s\n","MBC4: Based on Linux BCX by Mike Henning (c) 2009");
printf("%s%s\n","(c) 2009-2018 Armando Rivera with additional code (c) 2009 John Jacques",LF);
#endif
if(bitz==64)
{
printf("\n");
printf("%s\n","********************");
printf("%s\n","** 64 BIT VERSION **");
printf("%s%s\n","********************",LF);
}
}
if(inchr(command(1),"."))
{
strcpy(Cmd,command(1));
}
else
{
if(Exist(join(2,command(1),".bas")))
{
strcpy(Cmd, join(2,command(1),".bas"));
}
else if(Exist(join(2,command(1),".BAS")))
{
strcpy(Cmd, join(2,command(1),".BAS"));
}
}
if(!Exist(Cmd))
{
printf("\n");
printf("%s%s\n","FILE NOT FOUND: ",command(1));
FreeGlobals();
fflush(stdout);
exit(0);
}
strcpy(FileIn,Cmd);
if(CmdLineFileOut[0]==0)
{
strcpy(FileOut, join(2,left(Cmd,InstrRev(Cmd,".",0)-1),".cc"));
}
else
{
strcpy(FileOut,CmdLineFileOut);
}
strcpy(FileErr, join(2,left(Cmd,InstrRev(Cmd,".",0)-1),".ERR"));
if(Exist(FileErr))
{
remove (FileErr);
}
strcpy(prcFile,TempFileName(tempdir(),"prc"));
strcpy(udtFile,TempFileName(tempdir(),"udt"));
strcpy(datFile,TempFileName(tempdir(),"dat"));
strcpy(cstFile,TempFileName(tempdir(),"cst"));
strcpy(ovrFile,TempFileName(tempdir(),"ovr"));
strcpy(hdrFile,TempFileName(tempdir(),"hdr"));
strcpy(setFile,TempFileName(tempdir(),"set"));
strcpy(enuFile,TempFileName(tempdir(),"enu"));
if((SourceFile=fopen(FileIn,"r"))==0)
{
fprintf(stderr,"Can't open file %s\n",FileIn);
exit(1);
}
if((FP2=fopen(FileOut,"w"))==0)
{
fprintf(stderr,"Can't open file %s\n",FileOut);
exit(1);
}
Outfile=FP2;
if((FP3=fopen(prcFile,"w"))==0)
{
fprintf(stderr,"Can't open file %s\n",prcFile);
exit(1);
}
if((FP4=fopen(udtFile,"w"))==0)
{
fprintf(stderr,"Can't open file %s\n",udtFile);
exit(1);
}
if((FP5=fopen(datFile,"w"))==0)
{
fprintf(stderr,"Can't open file %s\n",datFile);
exit(1);
}
if((FP6=fopen(cstFile,"w"))==0)
{
fprintf(stderr,"Can't open file %s\n",cstFile);
exit(1);
}
if((FP7=fopen(hdrFile,"w"))==0)
{
fprintf(stderr,"Can't open file %s\n",hdrFile);
exit(1);
}
if((FP8=fopen(ovrFile,"w"))==0)
{
fprintf(stderr,"Can't open file %s\n",ovrFile);
exit(1);
}
if((FP9=fopen(setFile,"w"))==0)
{
fprintf(stderr,"Can't open file %s\n",setFile);
exit(1);
}
if((FP11=fopen(enuFile,"w"))==0)
{
fprintf(stderr,"Can't open file %s\n",enuFile);
exit(1);
}
ModuleNdx=1;
strcpy(Modules[ModuleNdx],FileIn);
ModuleLineNos[ModuleNdx]=0;
EmitProlog();
ClearIfThenStacks();
EmitCmdLineConst();
AddGlobal("G_argv",vt_PCHAR,0,"",1,0,0,0);
AddGlobal("G_argc",vt_INTEGER,0,"",0,0,0,0);
READSRCLINE:;
while(!EoF(SourceFile)||SplitCnt)
{
if(SplitCnt==0)
{
Src[0]=0;
AR_fgets_retval=fgets(Src,65535,SourceFile);
if(Src[strlen(Src)-1]==10)Src[strlen(Src)-1]=0;
ModuleLineNos[ModuleNdx]++;
StripCode(Src);
if(*Src==0)
{
continue;
}
if(JoinLines(Src)==1)
{
continue;
}
if(inchr(Src,"["))
{
BracketHandler(Src,0);
}
if(SplitLines(Src))
{
strcpy(Src,SplitStk[++SplitCur]);
}
}
else
{
strcpy(Src,SplitStk[++SplitCur]);
}
if(SplitCur==SplitCnt)
{
SplitCur=SplitCnt=0;
}
if(*Src==0)
{
continue;
}
strcpy(AbortSrc,Src);
if(TrcFlag&&InFunc)
{
if(!iMatchLft(Src,"$trace"))
{
if(!iMatchLft(Src,"end ")&&instr_b(Src,"FUNCTION",0,1)==0)
{
fprintf(Outfile,"%s%s%s%s%s%s\n","// [",trim(Modules[ModuleNdx])," - ",trim(str(ModuleLineNos[ModuleNdx])),"] ",Src);
strcpy(Z,trim(Modules[ModuleNdx]));
strcpy(Z,replace(Z,"\\","\\\\"));
strcpy(Z, join(5," ",Z," - ",str(ModuleLineNos[ModuleNdx])," \\n"));
strcpy(Z, join(3,"printf(",enc(Z),");"));
fprintf(Outfile,"%s\n",Z);
}
}
}
if(SrcFlag)
{
if(!iMatchLft(Src,"$sourc")&&*Src!=33)
{
fprintf(Outfile,"%s%s%s%s%s%s\n","// [",trim(Modules[ModuleNdx])," - ",trim(str(ModuleLineNos[ModuleNdx])),"] ",Src);
}
}
if(ShowStatus)
{
locate (2,1,0);
printf("%s%s%s%d\n","Processing Module: ",trim(Modules[ModuleNdx])," - Line:",(int)ModuleLineNos[ModuleNdx]);
}
if(Src[0]==33)
{
Src[0]=32;
fprintf(Outfile,"%s\n",Src);
*Src=0;
}
if(*Src==0)
{
continue;
}
int di;
di=Directives();
if(di==0)
{
goto READNEXTLINE;
}
if(di==1)
{
goto READSRCLINE;
}
if(iMatchLft(Src,"set "))
{
ProcessSetCommand(0);
}
if(iMatchLft(Src,"sharedset "))
{
ProcessSetCommand(1);
}
PassOne=TRUE;
CheckParQuotes();
if(SpecialCaseHandler(Src))
{
continue;
}
Parse(Src);
PassOne=FALSE;
if(Ndx)
{
Emit();
}
READNEXTLINE:;
}
if(CmdLineConst[0]>0)
{
strcpy(Src, join(2,"CONST ",CmdLineConst));
Parse(Src);
Emit();
*CmdLineConst=0;
}
if(TestForBcxIni==FALSE)
{
TestForBcxIni=TRUE;
strcpy(szFile, join(2,curdir(),"\\bcx.ini"));
if(!Exist(szFile))
{
strcpy(szFile, join(2,AppExePath(),"bcx.ini"));
}
if(Exist(szFile))
{
PushFileIO();
if((SourceFile=fopen(szFile,"r"))==0)
{
fprintf(stderr,"Can't open file %s\n",szFile);
exit(1);
}
strcpy(Modules[++ModuleNdx],szFile);
ModuleLineNos[ModuleNdx]=0;
goto READSRCLINE;
}
}
fflush(Outfile);
if(FPtrNdx)
{
PopFileIO();
goto READSRCLINE;
}
if(Use_GenFree&&GlobalDynaCnt)
{
MakeFreeGlobals();
}
ExportInternalConst();
EmitEpilog();
CloseAll();
AddProtos();
DeclareVariables();
AddFuncs();
CloseAll();
if(UseCpp&&str_cmp(CmdLineFileOut,"")==0)
{
strcpy(szTmp, join(2,extract(FileOut,"."),".cpp"));
remove (szTmp);
rename (FileOut,szTmp);
strcpy(FileOut,szTmp);
}
if(Use_Osx&&str_cmp(CmdLineFileOut,"")==0)
{
strcpy(szTmp, join(2,extract(FileOut,"."),".mm"));
remove (szTmp);
rename (FileOut,szTmp);
strcpy(FileOut,szTmp);
}
if((FP1=fopen(FileOut,"r"))==0)
{
fprintf(stderr,"Can't open file %s\n",FileOut);
exit(1);
}
if((FP2=fopen(hdrFile,"r"))==0)
{
fprintf(stderr,"Can't open file %s\n",hdrFile);
exit(1);
}
if((FP3=fopen("$temp$","w"))==0)
{
fprintf(stderr,"Can't open file %s\n","$temp$");
exit(1);
}
DoCountLines=TRUE;
fprintf(FP3,"%s\n","// *********************************************************************");
fprintf(FP3,"%s%s%s\n","// Created with MBC (V) ",Version,"Ported to OSX by Armando Rivera");
fprintf(FP3,"%s\n","// Ported from BCX32 BASIC To C/C++ Translator (V) 5.12");
fprintf(FP3,"%s\n","// BCX (c) 1999 - 2018 by Kevin Diggins");
fprintf(FP3,"%s\n","// LinuxBC (c) 2009 by Mike Henning ");
fprintf(FP3,"%s\n","// MBC (c) 2009 - 2018 by Armando Rivera");
fprintf(FP3,"%s\n","// *********************************************************************");
fprintf(FP3,"%s\n","// Translated for compiling with the g++ Compiler");
if(UseCpp)
{
fprintf(FP3,"%s\n","// g++ -Wformat -D_FORTIFY_SOURCE=2 -Wno-write-strings $FILE$.cpp -ldl -o $FILE$");
}
else
{
fprintf(FP3,"%s\n","// g++ -Wformat -D_FORTIFY_SOURCE=2 -Wno-write-strings $FILE$.cc -ldl -o $FILE$");
}
fprintf(FP3,"%s\n","// *********************************************************************");
if(NoRT==FALSE)
{
if(Use_Osx)
{
fprintf(FP3,"%s\n","#import <Cocoa/Cocoa.h>");
}
/*****2010-11-24AddedWxCFORWXCONSOLEApps-AIR*****/;
if(Use_Wx||Use_WxC)
{
fprintf(FP3,"%s\n","// WXWIDGETS HEADER FILES //");
fprintf(FP3,"%s\n","#include <wx/wx.h>");
fprintf(FP3,"%s\n","#include <wx/process.h>");
fprintf(FP3,"%s\n","#include <wx/txtstrm.h>");
fprintf(FP3,"%s\n","#include <wx/msgdlg.h>");
fprintf(FP3,"%s\n","#include <wx/stdpaths.h>");
fprintf(FP3,"%s\n","#include <wx/event.h>");
fprintf(FP3,"%s\n","// ******************* //");
fprintf(FP3,"%s\n","");
}
if(Use_Gtk)
{
fprintf(FP3,"%s\n","#include <gtk/gtk.h>");
}
if(Use_Glib)
{
fprintf(FP3,"%s\n","#include <glib.h>");
}
fprintf(FP3,"%s\n","#include <stdbool.h>");
fprintf(FP3,"%s\n","#include <ctype.h>");
fprintf(FP3,"%s\n","#include <math.h>");
fprintf(FP3,"%s\n","#include <stdio.h>");
fprintf(FP3,"%s\n","#include <iostream>");
fprintf(FP3,"%s\n","#include <fstream>");
fprintf(FP3,"%s\n","#include <string.h>");
fprintf(FP3,"%s\n","#include <stddef.h>");
fprintf(FP3,"%s\n","#include <stdlib.h>");
fprintf(FP3,"%s\n","#include <setjmp.h>");
fprintf(FP3,"%s\n","#include <time.h>");
fprintf(FP3,"%s\n","#include <stdarg.h>");
fprintf(FP3,"%s\n","#include <dirent.h>");
fprintf(FP3,"%s\n","#include <sys/types.h>");
fprintf(FP3,"%s\n","#include <sys/stat.h>");
fprintf(FP3,"%s\n","#include <sys/wait.h>");
fprintf(FP3,"%s\n","#include <unistd.h>");
fprintf(FP3,"%s\n","#include <dlfcn.h>");