Powerbasic Museum 2020-B

IT-Consultant: Patrice Terrier => C++ programming (SDK style) => Topic started by: Patrice Terrier on July 25, 2013, 12:23:52 PM

Title: Translating PB to C/C++
Post by: Patrice Terrier on July 25, 2013, 12:23:52 PM
ASC() ANSI version:

long asc(IN string s, IN long nPos) {
    long nRet = -1;
    long nLen = (long) s.length();
    if ((nLen == 0) || (nPos > nLen) || (nPos == 0)) { return nRet; }
    if (nPos > 0) {
        --nPos; }
    else {
        nPos = nLen + nPos; // Don't be fooled, despite the plus here, we remove the nPos value.
        if (nPos < 0) { return nRet; }
    }
    return (long) s[nPos];
}
Title: Translating PB to C/C++: TIME$()
Post by: Patrice Terrier on July 25, 2013, 12:27:07 PM
TIME$() Unicode version:

wstring TIME$() {
    time_t now = time(0);
    tm tstruct;
    WCHAR buf[16];
    if (localtime_s(&tstruct, &now) == 0) {;
        wcsftime(buf, sizeof(buf), L"%X", &tstruct);
    }
    return buf;
}
Title: Translating PB to C/C++: REPLACE ()
Post by: Patrice Terrier on July 25, 2013, 12:30:38 PM
REPLACE() Unicode version:

wstring REPLACE(IN wstring MainString, IN wstring MatchString, IN wstring NewString) {
    size_t pos = 0;
    while((pos = MainString.find(MatchString, pos)) != std::string::npos) {
         MainString.replace(pos, MatchString.length(), NewString);
         pos += NewString.length();
    }
    return MainString;
}
Title: Translating PB to C/C++: chr$()
Post by: Patrice Terrier on July 25, 2013, 12:33:30 PM
CHR$() ANSI version:

string chr$(IN long n) {
    char bb[2] = {0};
    bb[0] = n % 255;
    return (char*) bb;
}
Title: Translating PB to C/C++: EXTRACT$
Post by: Patrice Terrier on July 25, 2013, 03:59:52 PM
EXTRACT$() Unicode version:

wstring EXTRACT$(IN long nIndex, IN wstring sMain, IN wstring sSearch) {
    wstring sResult = sMain;
    long nLength = (long) sMain.length();
    long nRet = -1; // Not found
    if (nLength && (sSearch.length())) {
        if (nIndex < 0) {
            nRet = (long) sMain.rfind(sSearch, nLength + nIndex + 1); }
        else {
            nRet = (long) sMain.find(sSearch, nIndex);
        }
    }
    if (nRet > -1) { sResult = LEFT$(sMain, nRet); }
    return sResult;
}
Title: Translating PB to C/C++: MACRO + CONSTANT
Post by: Patrice Terrier on July 25, 2013, 04:41:04 PM
A few macro:

#define XOR ^
#define OR |
#define MOD %
#define ENDIF }
#define NEXT }


A few Unicode constants:

static wchar_t  *$NULL              = L"";
const wchar_t   *$DOT               = L".";
const wchar_t   *$ANTI              = L"\\";
const wchar_t   *$COMMA             = L",";
const wchar_t   *$SPACE             = L" ";
const wchar_t   *$ZLIM              = L"|";
const wchar_t   *$CHARNULL          = L"\0";
const wchar_t   *$CR                = L"\r";
const wchar_t   *$LF                = L"\n";
const wchar_t   *$TAB               = L"\t";
const wchar_t   *$SQUOTE            = L"'";
const wchar_t   *$DQUOTE            = L"\"";
Title: Re: Translating PB to C/C++
Post by: James C. Fuller on July 25, 2013, 06:45:07 PM
Good stuff Patrice keep em coming.

I am not a seasoned c++ coder but wouldn't wstring::npos be more politically correct?

wstring REPLACE(IN wstring MainString, IN wstring MatchString, IN wstring NewString) {
    size_t pos = 0;
    while((pos = MainString.find(MatchString, pos)) != wstring::npos) {
         MainString.replace(pos, MatchString.length(), NewString);
         pos += NewString.length();
    }
    return MainString;
}

James

Title: Re: Translating PB to C/C++
Post by: Patrice Terrier on July 25, 2013, 07:04:23 PM
wstring::npos, this constant means until the end of the wstring.
Title: Translating PB to C/C++: UCASE$ / LCASE$
Post by: Patrice Terrier on July 25, 2013, 07:12:32 PM
UCASE$() Unicode version:

wstring UCASE$(IN wstring sBuf) {
    std::transform(sBuf.begin(), sBuf.end(), sBuf.begin(), ::toupper);
    return sBuf;
}



LCASE$() Unicode version:

wstring LCASE$(IN wstring sBuf) {
    std::transform(sBuf.begin(), sBuf.end(), sBuf.begin(), ::tolower);
    return sBuf;
}
Title: Translating PB to C/C++: RTRIM$ / rtrim$
Post by: Patrice Terrier on July 25, 2013, 07:16:47 PM
RTRIM$() Unicode version:

wstring RTRIM$(IN wstring sBuf, IN wstring sChar) {
    wstring sResult = sBuf;
    LONG_PTR nLength = sBuf.length();
    if (nLength && (sChar.length())) {
        //sChar = sChar.substr(0, 1);
        while (nLength > 0) {
            // if (*sBuf.substr(nLength - 1, 1).c_str() == *sChar.c_str()) {
            // This is the sChar ANY search version
            if (std::wstring::npos != sChar.find(sBuf.substr(nLength - 1, 1))) {
                --nLength; }
            else {
                break;
            }
        }
        sResult = sBuf.substr(0, nLength);
    }
    return sResult;
}


rtrim$() ANSI version:

string rtrim$(IN string sBuf, IN string sChar) {
    string sResult = sBuf;
    long nLength = sBuf.length();
    if (nLength && (sChar.length())) {
        //sChar = sChar.substr(0, 1);
        while (nLength > 0) {
            // if (*sBuf.substr(nLength - 1, 1).c_str() == *sChar.c_str()) {
            // This is the sChar ANY search version
            if (std::string::npos != sChar.find(sBuf.substr(nLength - 1, 1))) {
                --nLength; }
            else {
                break;
            }
        }
        sResult = sBuf.substr(0, nLength);
    }
    return sResult;
}
Title: Translating PB to C/C++: UCODE$
Post by: Patrice Terrier on July 25, 2013, 07:28:34 PM
UCODE$() convert from ANSI to UNICODE.

wstring UCODE$(IN char* src) {
    return wstring(src, src + strlen(src));
}


Added:
And here is another variation based on a macro

#define UCODE$(str) ((WCHAR*) wstring(str.begin(), str.end()).c_str())
Title: Re: Translating PB to C/C++: ISFOLDER
Post by: Patrice Terrier on September 04, 2013, 04:30:08 PM
ISFOLDER() Unicode version:

BOOL ISFOLDER(IN WCHAR* wszPath) { // dllexport
    BOOL bRet = FALSE;
    DWORD ftyp = GetFileAttributes(wszPath);
    if ((ftyp != INVALID_FILE_ATTRIBUTES) && (ftyp & FILE_ATTRIBUTE_DIRECTORY)) { bRet = TRUE; }
    return bRet;
}
Title: Re: Translating PB to C/C++: ISFILE
Post by: Patrice Terrier on September 05, 2013, 09:37:05 AM
ISFILE() Unicode version:

BOOL ISFILE(IN WCHAR* Filename) {
    BOOL bRet = FALSE;
    DWORD ftyp = GetFileAttributes(Filename);
    if ((ftyp != INVALID_FILE_ATTRIBUTES) && ((ftyp & FILE_ATTRIBUTE_DIRECTORY) == 0)) { bRet = TRUE; }
    return bRet;
}


Note: like the original PowerBASIC function:
Filename is an unambiguous file name, which may not contain an asterisk (*) or query (?). If it contains one or more of those characters, the function always returns false (0).

If you want to use wildcard characters, then use this:
BOOL FileExist (IN wstring sFileSpec) {
    WIN32_FIND_DATA fd = { 0 };
    LPCTSTR lpFileSpec = sFileSpec.c_str();
    BOOL bRet = FALSE;
    if (sFileSpec.length()) {
       HANDLE hFind;
       hFind = FindFirstFile(sFileSpec.c_str(), &fd);
       if (hFind != INVALID_HANDLE_VALUE) {
          FindClose(hFind);
          bRet = TRUE;
       }
    }
    return bRet;
}
Title: Re: Translating PB to C/C++: LEFT$, RIGHT$, MID$
Post by: Patrice Terrier on September 05, 2013, 07:44:28 PM
LEFT$() Unicode version:

wstring LEFT$(IN wstring sBuf, IN long nLeft) {
    wstring sResult = $NULL;
    LONG_PTR nLength = max(min((long)sBuf.length(), nLeft), 0);
    if (nLength) {
        sResult = sBuf.substr(0, nLength);
    }
    return sResult;
}



RIGHT$() Unicode version:

wstring RIGHT$(IN wstring sBuf, IN long nRight) {
    wstring sResult = $NULL;
    LONG_PTR nLength = sBuf.length();
    if (nLength) { sResult = sBuf.substr(nLength - nRight, nRight); }
    return sResult;
}



MID$() Unicode version:

wstring MID$(IN wstring sBuf, IN long nStart, IN long nMid = 0) { // dllexport
    wstring sResult = $NULL;
    long nLength = (long) sBuf.length();
    if (nMid == 0) { nMid = nLength - nStart + 1; }
    if (nLength) { sResult = sBuf.substr(nStart - 1, nMid); }
    return sResult;
}
Title: Re: Translating PB to C/C++: INSTR
Post by: Patrice Terrier on September 05, 2013, 07:47:53 PM
INSTR() Unicode version:

long INSTR(IN long nIndex, IN wstring sMain, IN wstring sSearch) {
    long nRet = -1; // Not found
    long nLength = (long) (sMain.length());
    if (nLength && (sSearch.length())) {
        if (nIndex < 0) {
            nRet = (long) (sMain.rfind(sSearch, nLength + nIndex + 1)); }
        else {
            nRet = (long) (sMain.find(sSearch, nIndex));
        }
    }
    return nRet + 1;
}

Title: Re: Translating PB to C/C++: LTRIM$
Post by: Patrice Terrier on September 05, 2013, 07:54:55 PM
LTRIM$() Unicode version:

wstring LTRIM$(IN wstring sBuf, IN wstring sChar) { // dllexport
    wstring sResult = sBuf;
    LONG_PTR nLength = sBuf.length();
    if (nLength && (sChar.length())) {
        //sChar = sChar.substr(0, 1);
        long K = 0;
        while (K < nLength) {
            // if (*sBuf.substr(K, 1).c_str() == *sChar.c_str()) {
            // This is the sChar ANY search version
            if (std::wstring::npos != sChar.find(sBuf.substr(K, 1))) {
                ++K; }
            else {
                break;
            }
        }
        sResult = sBuf.substr(K, nLength);
    }
    return sResult;
}
}
Title: Re: Translating PB to C/C++: TRIM$
Post by: Patrice Terrier on September 05, 2013, 07:56:30 PM
TRIM$() Unicode version:

wstring TRIM$(IN wstring sBuf, IN wstring sChar) {
    return LTRIM$(RTRIM$(sBuf, sChar), sChar);
}

Title: Re: Translating PB to C/C++: PARSE$
Post by: Patrice Terrier on September 05, 2013, 07:57:40 PM
PARSE$() Unicode version:

wstring PARSE$(IN wstring sMain, IN wstring sDelim, IN long nIndex) {
    wstring sResult = $NULL;
    long nLength = (long) sDelim.length();
    if (nLength == 0) { sDelim = L","; ++nLength; } // Use comma "," as default delimiter
    sMain = RTRIM$(sMain, sDelim); sMain += sDelim;
    if (sMain.length() && nLength) {
        LONG_PTR prev_pos = 0, pos = 0, nCount = 0;
        while( (pos = sMain.find(sDelim, pos)) != std::wstring::npos ) {
            wstring substring(sMain.substr(prev_pos, pos - prev_pos));
            ++nCount;
            if (nCount == nIndex) { sResult = substring; break; }
            prev_pos = ++pos;
        }
    }
    return sResult;
}

Title: Re: Translating PB to C/C++: PARSECOUNT
Post by: Patrice Terrier on September 05, 2013, 07:59:19 PM
PARSECOUNT() Unicode version:

long PARSECOUNT(IN wstring MainString, IN wstring MatchString) {
    long count = 0;
    size_t pos = 0;
    while((pos = MainString.find(MatchString, pos)) != std::string::npos) {
         ++count; ++pos;
    }
    return count;
}

Title: Re: Translating PB to C/C++: HEX$
Post by: Patrice Terrier on September 05, 2013, 08:01:47 PM
HEX$() Unicode version:

wstring HEX$(IN long nVal) { // dllexport
    WCHAR hex[33] = {0};
    _ltow_s(nVal, hex, 16); // Use base 16 for Hexadecimal.
    return CharUpper(hex);
}

Title: Re: Translating PB to C/C++: STRING$
Post by: Patrice Terrier on September 05, 2013, 08:16:43 PM
STRING$() Unicode version:

wstring STRING$(IN long nCount, IN BYTE UseChar) {
    wstring sbuffer; sbuffer.assign(nCount, UseChar);
    return sbuffer;
}

Title: Re: Translating PB to C/C++: TempPath
Post by: Patrice Terrier on September 06, 2013, 07:28:37 PM
GetTempPath() Unicode version:

Retrieve the current TMP/TEMP path.

WCHAR* TempPath () {
    static WCHAR buf[MAX_PATH];
    long nSize = GetTempPath(GetTempPath(NULL, NULL), &buf[0]);
    wstring sTempPath = RTRIM$((wstring) buf, $ANTI);
    sTempPath += $ANTI;
    memset(&buf[0], 0, sizeof(buf));
    CopyMemory(&buf[0], (WCHAR*) sTempPath.c_str(), sTempPath.length() * 2);
    return buf;
}

Title: Re: Translating PB to C/C++: ExeName
Post by: Patrice Terrier on September 06, 2013, 07:33:07 PM
ExeName() Unicode version:

Retrieve the current EXE name.

static wchar_t  *$NULL = L"";

WCHAR* ExeName () {
    static WCHAR buf[MAX_PATH];
    if (GetModuleFileName(NULL, buf, MAX_PATH)) {
        return buf;}
    else {
        return $NULL;
    }
}

Title: Translating PB to C/C++: Replacement for SELECT CASE AS CONST$
Post by: Patrice Terrier on September 11, 2013, 06:00:18 PM
There is no built-in function to perform a SELECT CASE AS CONST$ in C/C++

Here is a replacement that would do it, using a hash function to turn the char string into a DWORD, in order to perform the switch/case as fast as possible.

The hash function:
DWORD hashStr(IN char* szText){
    DWORD hash = 0, nLen = (long) strlen(szText), K;
    if (nLen > 0) {
        for (K = 0; K < nLen; K++) {
            hash = (K * hash) + szText[K];
        }
    }
    return hash;
}

Note: You must insure that the hash function doesn't produce any collision.


and how to use it:
BOOL CALLBACK EnumChildProc(IN HWND hWnd, IN LPARAM lParam) {
    char zChildClass[64] = {0};

    if (GetClassNameA(hWnd, zChildClass, sizeof(zChildClass))) {

       CharUpperA(zChildClass);

       switch (hashStr(zChildClass)) {

       case 7925100: // "MDICLIENT"
            break;
       case 3961174590: // "TOOLBARWINDOW32"
            break;
       case 1881446725: // "MSCTLS_STATUSBAR32"
            break;
       case 25313: // "BUTTON"
            break;
       case 570326284: // "SYSTABCONTROL32"
            break;
       case 14743: // "#32770"
            break;
       case 26052: // "STATIC"
            break;
       case 3565744546: // "SYSTREEVIEW32"
            break;
       case 149782: // "LISTBOX"
            break;
       case 3878117282: // "MSCTLS_TRACKBAR32"
            break;
       case 2813312866: // "SYSLISTVIEW32"
            break;
       case 831093140: // "SYSHEADER32"
            break;
       case 1028461: // "RICHEDIT"
            break;
       case 1005323: // "COMBOBOX"
            break;
       case 1125: // "EDIT"
            break;
       case 876965674: // "REBARWINDOW32"
            break;
       case 991760690: // "MSCTLS_PROGRESS32"
            break;
       case 728101136: // "MSCTLS_UPDOWN32"
            break;
       case 78374326: // "ZIMAGECTRL"
            break;
       case 814530776: // "ZOPENGLCTRL"
            break;
       default:
            break;
       }
    }
    return TRUE;   // continue enumeration of children...
}
Title: Re: Translating PB to C/C++
Post by: James C. Fuller on September 11, 2013, 07:17:22 PM
Patrice,
  I am not a big fan of the c++ switch case so I am glad I don't have to work with it.
All Select Case in bc9Basic is translated to if statements.

This bc9Basic code

'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
'Select case test with stdstr
'=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*
$CPPHDR
$NOMAIN
$ONEXIT "GWGPP481.BAT $FILE$ -m32 con"

Function main() As int
    Raw As std::string s1 = "button"

    Select Case Ucase$(s1.c_str())
        Case "TOOLBARWINDOW32"
            Print "TOOLBARWINDOW32"
        Case "MSCTLS_STATUSBAR32"
            Print "MSCTLS_STATUSBAR32"
        Case "BUTTON"
            Print "BUTTON"
        Case Else
            Print "No Match"   
    End Select
    pause
End Function




Is translated to


int main (int argc,PCHAR* argv)
{
  g_argc= argc;
  g_argv= argv;
  std::string  s1="button";
  if(str_cmp(ucase(s1.c_str()),"TOOLBARWINDOW32")==0)
    {
      printf("%s\n","TOOLBARWINDOW32");
      goto L1000;
    }
  if(str_cmp(ucase(s1.c_str()),"MSCTLS_STATUSBAR32")==0)
    {
      printf("%s\n","MSCTLS_STATUSBAR32");
      goto L1000;
    }
  if(str_cmp(ucase(s1.c_str()),"BUTTON")==0)
    {
      printf("%s\n","BUTTON");
    }
  else // case else
    {
      printf("%s\n","No Match");
    }
L1000:;
  Pause();
  return 0;
}


James
Title: Re: Translating PB to C/C++
Post by: Patrice Terrier on September 11, 2013, 07:53:52 PM
James;

In case of many IF statement, that is very hard to read and maintain.

Swicth case is highly optimized, and no need to check for each conditions first.

...
Title: Re: Translating PB to C/C++
Post by: James C. Fuller on September 11, 2013, 08:18:46 PM
Quote from: Patrice Terrier on September 11, 2013, 07:53:52 PM
James;

In case of many IF statement, that is very hard to read and maintain.

Swicth case is highly optimized, and no need to check for each conditions first.

...

I agree but I don't have to deal with it . Let the translator do it's work! :)

The switch case may be highly optimized, but as you have found, it has more limitations than the standard "BASIC" implementation.

I do appreciate you sharing so please don't hesitate to post as many conversions as you can. My C++ is abysmal so don't take anything I post too seriously :)

James
 


Title: Re: Translating PB to C/C++
Post by: Patrice Terrier on September 11, 2013, 09:36:10 PM
James,

From what i can see, the code translation in your example is really not optimized.
It does the ucase(s1.c_str()) in each of the IF, instead of doing it only once.

For me it is clear that no translator could come close to hand crafted code :)
Title: Re: Translating PB to C/C++
Post by: James C. Fuller on September 11, 2013, 10:05:29 PM
Well that's my fault in not optimizing it in the first place and not calling ucase in the select statement.
As long as I don't have to deal with all the c++ braces and semi colons :) I'll live with a little less optimization.
But when it's needed I can use straight c++ or assembler.

James

Title: Re: Translating PB to C/C++
Post by: Daniel Corbier on September 13, 2013, 02:52:20 PM
I'm glad I'm not the only person who wants to convert PowerBASIC source code to C++.  I created a tool named uCalc Transform that is specifically designed to help translate source code (among other uses).  This is what I intend to use to make my PB-written software available on other platforms (Android, Mac OS, Linux, etc), and also to create a 64-bit version of my uCalc Fast Math Parser DLL.  I already use it to auto-generate the headers for Delphi, C#, Visual Basic.NET, VB6, and various flavors of C++, taking PB source code as input.

I started an Open Source PB to C++ project.  Please join me to help complete the project.  Visit:

https://github.com/uCalc/powerbasic-to-cpp
Title: Re: Translating PB to C/C++
Post by: James C. Fuller on September 13, 2013, 04:23:36 PM
Quote from: Daniel Corbier on September 13, 2013, 02:52:20 PM
I'm glad I'm not the only person who wants to convert PowerBASIC source code to C++.  I created a tool named uCalc Transform that is specifically designed to help translate source code (among other uses).  This is what I intend to use to make my PB-written software available on other platforms (Android, Mac OS, Linux, etc), and also to create a 64-bit version of my uCalc Fast Math Parser DLL.  I already use it to auto-generate the headers for Delphi, C#, Visual Basic.NET, VB6, and various flavors of C++, taking PB source code as input.

I started an Open Source PB to C++ project.  Please join me to help complete the project.  Visit:

https://github.com/uCalc/powerbasic-to-cpp

It appears one has to purchase your Transform app in order to participate in an Open Source project?

James
Title: Re: Translating PB to C/C++
Post by: Daniel Corbier on September 13, 2013, 06:26:19 PM
As I clarified in http://www.powerbasic.com/support/pbforums/showthread.php?t=53538 there is no requirement to pay to participate in the project.  uCalc Transform will display 2 messages boxes to those who haven't purchased a license.  However, beyond that the download is fully functional, with no time limits.  uCalc Transform is a commercial product.  The Open Source tool is the PB to C++ converter.  Basically I want everyone to join the project, regardless of whether they purchase a license for uCalc Transform.  I'm open to ideas about licensing options in case there's any concern.
Title: Re: Translating PB to C/C++: IF equality comparison pitfall
Post by: Patrice Terrier on September 14, 2013, 04:26:54 PM
The IF equal comparison pitfall.

PowerBASIC code:
QuoteIF uMsg = WM_PAINT THEN

must be translated to
if (uMsg == WM_PAINT) {

unfortunatly, when you have a huge PB background, it is easy to forget one of the =, and write
if (uMsg = WM_PAINT) {
producing unexpected results, and hard to find bug...
Title: Re: Translating PB to C/C++
Post by: Kev Peel on September 15, 2013, 12:27:36 PM
See my post about #pragma warning
http://www.jose.it-berater.org/smfforum/index.php?topic=4698.0
Title: Re: Translating PB to C/C++
Post by: Patrice Terrier on September 15, 2013, 12:53:08 PM
I should have re-read my own thread  :-[
Title: Re: Translating PB to C/C++
Post by: James C. Fuller on September 15, 2013, 09:38:45 PM
Patrice,
  Are you using any of the STL containers? (array,vector,deque,list).
For me the vector is the most important entity in C++.
The highly recommended book "Accelerated C++ Practical Programming by Example" starts right out with vectors

James
Title: Re: Translating PB to C/C++
Post by: Patrice Terrier on September 15, 2013, 10:22:50 PM
James--

WinLIFT
Quotevector<BYTE>           g_ByteArray;
vector<MEMBMP>         g_MemBmp;
vector<long>           g_nColor;
vector<long>           g_nMetrics;
vector<HWND>           g_SysBut;
vector<MAINPROPERTY>   g_Win;
vector<CHILDPROPERTY>  g_Child;
vector<ZSCROLLINFO>    g_SI;
vector<wstring>        g_sCfg;
vector<SKINCHECK>      g_NoSkin;
vector<HWND>           g_Zorder;
vector<ANCHORPROPERTY> g_Prop;
vector<MENUITEMS>      g_Mi;
vector<long>           g_mSkin;
vector<RECT>           g_rcb;
vector<ANCHORCTRL>     g_Chor;

;D
Title: Re: Translating PB to C/C++
Post by: James C. Fuller on September 16, 2013, 12:42:37 AM

I also like the new c++(11) auto variables and range based for but unfortunately my VC++ from the Win7 SDK doesn't have it.
Will this compile with your VC++?
This compiles fine with the latest MinGW 4.8.1
James



#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main ()
{
// this is new for c++(11)
  vector<wstring>  s={L"one",L"two",L"three",L"four",L"five"};
  cout<<"s contains"<<endl;

// new c11 automatic variables 
  for(auto it=s.begin();it!=s.end();++it)
    {
      wcout<<" "<<*it;
    }

  cout<<endl;
  cout<<"in reverse"<<endl;
  for(auto rit=s.rbegin();rit!=s.rend();++rit)
    {
      wcout<<" "<<*rit;
    }

  cout<<endl;

// range based for loop 
  cout<<"range-based for loop"<<endl;
for ( auto it : s)
    {
      wcout<<" "<<it;
    }

//sort it
  cout<<endl;
  cout<<"sort it "<<endl;
  std::sort(s.begin(),s.end());

// another range based for
for ( auto it : s)
    {
      wcout<<" "<<it;
    }

  cout<<endl;
  system("pause");
  return 0;
}



output:

s contains
one two three four five
in reverse
five four three two one
range-based for loop
one two three four five
sort it
five four one three two
Title: Re: Translating PB to C/C++
Post by: Daniel Corbier on September 16, 2013, 08:12:49 PM
I probably should have started my own separate thread to talk about my PB to C++ open source project, instead of inserting my announcement here.  Sorry about that.   So a moment ago, I posted the announcement (http://www.jose.it-berater.org/smfforum/index.php?topic=4799.0) in the general forum instead.

But in this thread you (Patrice) mentioned the thing about "=" vs "==".  With uCalc Transform, here's one approach:

(http://www.ucalc.com/images/misc/equal.png)

Basically this tells it to replace all occurrences of "=" with "==", except for those patterns that are marked with the "Skip over" property.  Those patterns are for equate definitions or variable assignments, defined as a new line, colon, or "Then" keyword immediately followed by one followed by the equal sign.  All other equal signs are modified.  What do you think of that?

Here an example of some code before changes:

%abc = &H100

If x = 456 Then
  y = y+1 : n = 15
  z = x = y
  Print x = 5
  If z > 10 Then Result = 25
End If


Here's what it would look like afterwards:



%abc = &H100

If x == 456 Then
  y = y+1 : n = 15
  z = x == y
  Print x == 5
  If z > 10 Then Result = 25
End If




Then the code can be converted to C++.
Title: Re: Translating PB to C/C++ UCODE$ macro
Post by: Patrice Terrier on September 25, 2013, 03:04:20 PM
UCODE$

I have added a macro definition that could also be used for UCODE$ replacement.

The macro is here (http://www.jose.it-berater.org/smfforum/index.php?topic=4725.msg18569#msg18569)
Title: Re: Translating PB to C/C++
Post by: James C. Fuller on November 02, 2013, 07:10:26 PM
Patrice,
  How would you go about SHRINK$?

I have a "c" version from bcx STRIM$ but not sure how to approach a wstring version.

I suppose I could cheat and convert the wstring to ansi, run it through STRIM$ and then convert back to wstring :)

James
Title: Re: Translating PB to C/C++
Post by: José Roca on November 02, 2013, 07:22:31 PM
> I suppose I could cheat and convert the wstring to ansi, run it through STRIM$ and then convert back to wstring

Would be funny to see the result if used by someone that really needs unicode (Chinese, etc.).
Title: Re: Translating PB to C/C++
Post by: James C. Fuller on November 02, 2013, 08:20:51 PM
José,
  That brings up a point if a UNICODE application is really the correct direction for euro/usa users?
I have never encountered a unicode file in all the source code I have downloaded. It seems like it would just add more complexity and confusion to my apps

James
Title: Re: Translating PB to C/C++
Post by: Patrice Terrier on November 02, 2013, 08:43:23 PM
Long before SHRINK$, i wrote that one, that should not be too hard to translate. :)

QuoteFUNCTION Crunch(BYREF sExpr AS STRING, BYVAL UseChar AS BYTE) AS LONG
' Remove all extra chars left, right and inside sExpr
' such to have only one char between each string member.
' CHR$(0) are considerd as spaces.
' Function returns the number of string members found in sExpr
'
    LOCAL So, cMember AS LONG
    LOCAL sStrip AS STRING
    IF UseChar = 32 THEN REPLACE CHR$(0) WITH CHR$(32) IN sExpr
    sExpr = TRIM$(sExpr): sStrip = CHR$(UseChar)
    IF LEN(sExpr) THEN
       So = 1: nMember = 1
       DO
          So = INSTR(So, sExpr, sStrip)
          IF So THEN
             sExpr = LEFT$(sExpr, So) + LTRIM$(MID$(sExpr, So + 1))
             So += 1: nMember += 1
          END IF
       LOOP UNTIL So = 0
    END IF
    FUNCTION = nMember

END FUNCTION
Title: Re: Translating PB to C/C++
Post by: James C. Fuller on November 03, 2013, 04:17:27 PM
Patrice,
  Got it.
Plus I found a couple other useful(?) functions to convert to/from string/wstring
They need a better name

James



#define WAITKEY system("pause")
//==============================================================================
std::string valueOf(std::wstring& str) {
    std::string ss;
    ss.assign(str.begin(), str.end());
    return ss;
}
//------------------------------------------------------------------------------

std::wstring valueOf(std::string& str) {
    std::wstring ss;
    ss.assign(str.begin(), str.end());
    return ss;
}
//==============================================================================
std::string SSTRIM(std::string s)
{
    std::istringstream iss(s);
    s = "";
    std::string ss;
    while(iss >> ss)
    {
        if(s != "") s += " " + ss;
        else s = ss;
    }
    return s;
}
//------------------------------------------------------------------------------
std::wstring SSTRIM(std::wstring s)
{
    std::wistringstream iss(s);
    s = L"";
    std::wstring ss;
    while(iss >> ss)
    {
        if(s != L"") s += L" " + ss;
        else s = ss;
    }
    return s;
}
//==============================================================================

int main (int argc, PCHAR* argv)
{
    wstring  ws = L"     abc   def james                c.  fuller \t\t xyz    ";
    wstring  ws2;
    wcout << ws << endl;
    ws2 = SSTRIM( ws);
    wcout << ws2 << endl;
    WAITKEY;
}

Title: Re: Translating PB to C/C++
Post by: James C. Fuller on November 01, 2014, 03:20:23 PM
Patrice,
  What are you using for c++ Random file access of a typical PowerBasic TYPE ?

James
Title: Re: Translating PB to C/C++
Post by: Patrice Terrier on November 01, 2014, 04:44:02 PM
James--

I am using something like that:

ReadFile(fHandle, &ga_Sprite[0], BufferSize, &dwBytes, NULL);

Where BufferSize matches either the size of an array, or the size of a specific fixed record.

...
Title: Re: Translating PB to C/C++
Post by: James C. Fuller on November 02, 2014, 12:53:02 PM
Patrice,
  Did you do any speed/size tests using <fstream> ,<cstdio>, and  api (CreateFile,Read,Write)?

James
Title: Re: Translating PB to C/C++
Post by: Patrice Terrier on November 02, 2014, 01:35:34 PM
James--

Direct use of API (CreateFile,Read,Write), definitly produces smaller/faster code.
I am using them from the origine, and i have written a couple of functions that are working exactly like those of Ethan Winer (FOpen) and Charles Petzold.

Each time you use directly the flat API, you bypass any kind of CRT, what ever the language being used.

Example of generic FOpen function
function FOpen (szFileName as asciiz, byval AccessMode as long, byval ShareMode as long, byref hFile as long) as long

    LOCAL AccessIs, ShareIs, FlagAndAttribute as long

    AccessMode = min&(max&(AccessMode, 0), 2)     '// Coherce between 0-2
    if (AccessMode = 0) then                      '// 0 Open for read only.
        AccessIs = %GENERIC_READ
    elseif AccessMode = 1 then                    '// 1 Open for write only.
        AccessIs = %GENERIC_WRITE
    else                                          '// 2 Open for read and write.
        AccessIs = %GENERIC_READ OR %GENERIC_WRITE
    end if

    ShareMode = MIN(MAX(ShareMode, 1), 4)         '// Coherce between 1-4
    if ShareMode = 1 then                         '// 1 Deny read/write access.
       ShareIs = 0
    elseif ShareMode = 2 then                     '// 2 Deny write access.
       ShareIs = %FILE_SHARE_READ
    elseif ShareMode = 3 then                     '// 3 Deny read access.
       ShareIs = %FILE_SHARE_WRITE
    else                                          '// 4 Deny none (full share mode).
       ShareIs = %FILE_SHARE_READ OR %FILE_SHARE_WRITE
    end if

    if (hFile = -1) then
        FlagAndAttribute = %FILE_ATTRIBUTE_NORMAL OR %FILE_FLAG_WRITE_THROUGH
    else
        FlagAndAttribute = %FILE_ATTRIBUTE_NORMAL
    end if

    hFile = CreateFile(szFileName, AccessIs, ShareIs, byval %NULL, %OPEN_ALWAYS, FlagAndAttribute, byval %NULL)

    if (hFile = CLNG(%INVALID_HANDLE_VALUE)) then '// -1 Fail to create the file
        function = GetLastError()                 '// Set the error code
        hFile = 0                                 '// Reset handle number
    end if

end function



Title: Re: Translating PB to C/C++
Post by: James C. Fuller on December 04, 2014, 02:18:33 PM
Patrice,
  What are you using for PowerBASIC REDIM / REDIM PRESERVE replacement?

James
Title: Re: Translating PB to C/C++
Post by: Patrice Terrier on December 04, 2014, 03:01:36 PM
Vector.resize
Title: Re: Translating PB to C/C++
Post by: James C. Fuller on December 04, 2014, 03:45:04 PM
Patrice,
  Thanks I knew that :) and is what I use for c++

I'm doing a bit of "c" now and will revert to the malloc series I guess.

James
Title: Re: Translating PB to C/C++
Post by: Patrice Terrier on December 04, 2014, 03:59:48 PM
Then alloc a larger buffer than needed, and create a new one, only if the extra member couldn't fit in memory.
That would avoid to cause memory fragmentation.

...