• Welcome to Powerbasic Museum 2020-B.
 

News:

Forum in repository mode. No new members allowed.

Main Menu

REPLACE

Started by Patrice Terrier, May 23, 2017, 09:32:04 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Patrice Terrier

James

Do you have a BC9 example showing how the PB's REPLACE statement is translated to WCHAR ?
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

James C. Fuller

Patrice,
  This is  bc9Basic's REPLACE x WITH y IN z implementation code

$CPP
$ONEXIT "ULEX.EXE $FILE$.CPP TCHARXLATER_VC.TXT"
$ONEXIT "TCLIB.BAT $FILE$"         
'==============================================================================
Dim a$
a$ = "I Want To Go Here And Here And Here And Here And Here!"
REPLACE "Here"  With  "There" In a$
PRINT a$
Pause
'==============================================================================


produces this c++ code.
Remember the process I use with bc9Basic is all code is ansi, but is then run through the ULEX
utility to produce unicode.

// *********************************************************************
//  Created with bc9Basic - BASIC To C/C++ Translator (V) 9.2.7.0 (2017/03/31)
//       The bc9Basic translator (bc9.exe) was compiled with
//                           g++ (tdm64-1) 5.1.0
// ----------------------------------------------------------------------
//                 BCX (c) 1999 - 2009 by Kevin Diggins
// *********************************************************************
//              Translated for compiling with the
//           Microsoft (R) C/C++ Optimizing Compiler
//                           On MS Windows
//                    Using TCLib by Fred Harris
// *********************************************************************
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
#define _X(y) y
#include <windows.h>
#define   x64
#include "TCLib\stdio.h"
#include "TCLib\string.h"
#include "TCLib\stdlib.h"
#include "TCLib\memory.h"
#include "TCLib\malloc.h"
#include "TCLib\math.h"
#include "TCLib\tchar.h"
#include "TCLib\Strings.cpp"
typedef String fstring;
FILE* stdin;
FILE* stdout;
FILE* stderr;
//<---UNICODE AWARE
#define SFMT (const char*)"%s\r\n"
//>---UNICODE AWARE

// NO HEADERS START
#ifndef _WINDOWS_
//<---UNICODE AWARE
typedef _TCHAR *PCHAR, *LPCH, *PCH, *NPSTR, *LPSTR, *PSTR;
typedef unsigned long DWORD, *PDWORD, *LPDWORD;
typedef unsigned int UINT;
//>---UNICODE AWARE
#endif
// NO HEADERS END

// ***************************************************
// Compiler Defines
// ***************************************************

// C++
#if defined( __cplusplus )
#define overloaded
#define C_EXPORT EXTERN_C __declspec(dllexport)
#define C_IMPORT EXTERN_C __declspec(dllimport)
#define BEGIN_EXTERN_C        extern _T("C") {
#define END_EXTERN_C        }
#else
#define C_EXPORT __declspec(dllexport)
#define C_IMPORT __declspec(dllimport)
#endif


// Microsoft VC++
#ifndef DECLSPEC_UUID
#if (_MSC_VER >= 1100) && defined ( __cplusplus )
#define DECLSPEC_UUID(x)    __declspec(uuid(x))
#else
#define DECLSPEC_UUID(x)
#endif
#endif

// ***************************************************
// Compiler Defines
// ***************************************************
#ifndef __cplusplus
#error A C++ compiler is required
#endif

// *************************************************
//        User's GLOBAL ENUM blocks
// *************************************************

// *************************************************
//            System Defined Constants
// *************************************************

typedef const _TCHAR* ccptr;
#define CCPTR const _TCHAR*
#define cfree free
//<---UNICODE AWARE
typedef char _char;
#define _strlen strlen
//>---UNICODE AWARE
#define EQU ==
#define NOT_USED(x) if(x);
#define CTLHNDL(id) GetDlgItem(hWnd,id)
_TCHAR   *g_cptr_;  // dummy var for not used returns
unsigned int  g_dum1_;  // dummy var for not used returns
int g_dum_int;        // dummy int var for not used returns
#define cSizeOfDefaultString 2048

// *************************************************
//            User Defined Constants
// *************************************************


// *************************************************
//               Standard Prototypes
// *************************************************

_TCHAR*   BCX_TmpStr(size_t, size_t = 0, int = 1);
_TCHAR*   replace (const _TCHAR*, const _TCHAR*, const _TCHAR*);
_TCHAR    *_tcsstr_(_TCHAR*, _TCHAR*);
void    Pause (void);

// *************************************************
//                System Variables
// *************************************************

// *************************************************
//          User Defined Types, Unions and Classes
// *************************************************


// *************************************************
//            User Global Variables
// *************************************************

static _TCHAR    a[cSizeOfDefaultString];


// *************************************************
//            User Global Initialized Arrays
// *************************************************



// *************************************************
//                 Runtime Functions
// *************************************************

#ifndef BCXTmpStrSize
#define BCXTmpStrSize  2048
#endif
_TCHAR *BCX_TmpStr (size_t Bites, size_t  iPad, int iAlloc)
{
    static int   StrCnt;
    static _TCHAR *StrFunc[BCXTmpStrSize];
    StrCnt = (StrCnt + 1) & (BCXTmpStrSize - 1);
    if(StrFunc[StrCnt]) {
        free (StrFunc[StrCnt]);
        StrFunc[StrCnt] = NULL;
    }
#if defined BCX_MAX_VAR_SIZE
    if(Bites * sizeof(_TCHAR) > BCX_MAX_VAR_SIZE)
    {
        _tprintf(_T("Buffer Overflow caught in BCX_TmpStr - requested space of %d EXCEEDS %d\n"), (int)(Bites * sizeof(_TCHAR)), BCX_MAX_VAR_SIZE);
        abort();
    }
#endif
    if(iAlloc) StrFunc[StrCnt] = (_TCHAR*)calloc(Bites + iPad + 1, sizeof(_TCHAR));
    return StrFunc[StrCnt];
}


_TCHAR *replace (const _TCHAR *src, const _TCHAR *pat, const _TCHAR *rep)
{
    size_t patsz, repsz, tmpsz, delta;
    _TCHAR *strtmp, *p, *q, *r;
    if (!pat || !*pat)
    {
        strtmp = BCX_TmpStr(_tcslen(src), 1, 1);
        if (!strtmp) return NULL;
        return _tcscpy(strtmp, src);
    }
    repsz = _tcslen(rep);
    patsz = _tcslen(pat);
    for (tmpsz = 0, p = (_TCHAR*)src; (q = _tcsstr_(p, (_TCHAR*)pat)) != 0; p = q + patsz)
        tmpsz += (size_t) (q - p) + repsz;
    tmpsz += _tcslen(p);
    strtmp = BCX_TmpStr(tmpsz, 1, 1);
    if (!strtmp) return NULL;
    for (r = strtmp, p = (_TCHAR*)src; (q = _tcsstr_(p, (_TCHAR*)pat)) != 0; p = q + patsz)
    {
        delta = (size_t) (q - p);
        wmemcpy(r, p, delta);
        r += delta;
        _tcscpy(r, rep);
        r += repsz;
    }
    _tcscpy(r, p);
    return strtmp;
}


void Pause(void)
{
    _tprintf(_T("\n%ls\n"), _T("Press any key to continue..."));
    _getwch();
}


_TCHAR *_tcsstr_(_TCHAR *String, _TCHAR *Pattern)
{
    int   mi = -1;
    while(Pattern[++mi])
    {
        if(String[mi] == 0) return 0;
        if(String[mi] != Pattern[mi])
        {
            String++;
            mi = -1;
        }
    }
    return String;
}



// *************************************************
//       User Subs, Functions and Class Methods
// *************************************************

// *************************************************
//                  Main Program
// *************************************************

int _tmain(int argc, _TCHAR *argv[])
{
    _tcscpy(a, _T("I Want To Go Here And Here And Here And Here And Here!"));
    _tcscpy(a, replace(a, _T("Here"), _T("There")));
    _tprintf(_T("%ls\n"), a);
    Pause();
    return 0;   /* End of _tmain program */
}


James

Patrice Terrier

Thank you!

However i couldn't get this replace code to work by me

WCHAR* _tcsstr_(WCHAR* String, WCHAR* Pattern) {
    int   mi = -1;
    while(Pattern[++mi]) {
        if(String[mi] == 0) return 0;
        if(String[mi] != Pattern[mi])
        {
            String++;
            mi = -1;
        }
    }
    return String;
}

#ifndef BCXTmpStrSize
#define BCXTmpStrSize  2048
#endif
WCHAR *BCX_TmpStr (size_t Bites, size_t  iPad, int iAlloc)
{
    static int   StrCnt;
    static WCHAR *StrFunc[BCXTmpStrSize];
    StrCnt = (StrCnt + 1) & (BCXTmpStrSize - 1);
    if(StrFunc[StrCnt]) {
        free (StrFunc[StrCnt]);
        StrFunc[StrCnt] = NULL;
    }
#if defined BCX_MAX_VAR_SIZE
    if(Bites * sizeof(_TCHAR) > BCX_MAX_VAR_SIZE)
    {
        _tprintf(_T("Buffer Overflow caught in BCX_TmpStr - requested space of %d EXCEEDS %d\n"), (int)(Bites * sizeof(_TCHAR)), BCX_MAX_VAR_SIZE);
        abort();
    }
#endif
    if(iAlloc) StrFunc[StrCnt] = (WCHAR*)calloc(Bites + iPad + 1, sizeof(WCHAR));
    return StrFunc[StrCnt];
}


WCHAR *replace (const WCHAR *src, const WCHAR *pat, const WCHAR *rep)
{
    size_t patsz, repsz, tmpsz, delta;
    WCHAR *strtmp, *p, *q, *r;
    if (!pat || !*pat)
    {
        strtmp = BCX_TmpStr(wcslen(src), 1, 1);
        if (!strtmp) return NULL;
        return wcscpy(strtmp, src);
    }
    repsz = wcslen(rep);
    patsz = wcslen(pat);
    for (tmpsz = 0, p = (WCHAR*)src; (q = _tcsstr_(p, (WCHAR*)pat)) != 0; p = q + patsz)
        tmpsz += (size_t) (q - p) + repsz;
    tmpsz += wcslen(p);
    strtmp = BCX_TmpStr(tmpsz, 1, 1);
    if (!strtmp) return NULL;
    for (r = strtmp, p = (WCHAR*)src; (q = _tcsstr_(p, (WCHAR*)pat)) != 0; p = q + patsz)
    {
        delta = (size_t) (q - p);
        CopyMemory(r, p, delta);
        r += delta;
        wcscpy(r, rep);
        r += repsz;
    }
    wcscpy(r, p);
    return strtmp;
}
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

James

Just in case, here is the function i wrote to match my need

WCHAR* Replace(IN WCHAR* zMain, IN WCHAR* zSearch, IN WCHAR* zReplace) {
    static WCHAR sResult[512];
    ZeroMemory(sResult, 512 * sizeof(WCHAR));

    long nMain = (long)wcslen(zMain);
    long nSearch = (long)wcslen(zSearch);
    WCHAR* zParse = new WCHAR[nMain];
    long K = 0, nFound = 0, nStart = 0, ptr = 0;

    for (K = 0; K < nMain; K++) {
        if (zMain[K] == zSearch[nFound]) {
            nFound++;
            if (nStart == 0) { nStart = K; }
        } else if (nFound) {
            if (nFound == nSearch) {
                ZeroMemory(zParse, nMain * sizeof(WCHAR));
                MoveMemory(&zParse[0], &zMain[ptr], (nStart - ptr) * sizeof(WCHAR));
                AddStr(sResult, zParse); AddStr(sResult, zReplace);
                ptr = nStart + nSearch;
                nFound = 0; nStart = 0;
            } else if (nFound) {
                if (zMain[K] != zSearch[nFound]) {
                    nFound = 0; nStart = 0;
                }
            }
        }
    }

    if ((ptr > 0) && (nMain > ptr)) {
        ZeroMemory(zParse, nMain * sizeof(WCHAR));
        MoveMemory(&zParse[0], &zMain[ptr], (nMain - ptr) * sizeof(WCHAR));
        AddStr(sResult, zParse);
    }
    delete [] zParse;
    return sResult;
}


with minor change i could also use it to parse a string.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

James C. Fuller

Patrice,
  I don't know what the problem may be?
Bcx/Bc9 uses a circular buffer for returning strings (char[]/wchar[]) from functions.
I have never had any issues with it, although I thought I might with wchar[]'s.

I found out when using the stl string/wstring you don't have to worry about it. The compiler will do the copy from a local string to your calling var for you. I thought this was just an stl function but it seems it's for all classes.
I have used Fred's String class this way with no issues.
Yes you do have the overhead but it's not much with Fred's String class.

In your replace function example you are modifying the main string where the bc9 replace does not.

Try it with my tchar.h and see if that helps.
James
tchar.h

// tchar.h
#ifndef tchar_h
   #define tchar_h
   #ifdef  _UNICODE
      typedef wchar_t     TCHAR;
      typedef wchar_t     _TCHAR;
      #define _T(x)       L## x
      #define _tmain      wmain
      #define _tWinMain   wWinMain
      #define _tfopen     _wfopen
      //#define _fgetts     fgetws
      #define _fgetts     fgetws
      #define _tprintf    wprintf
      #define _ftprintf   fwprintf
      //#define _ftprintf   fprintf
      #define _stprintf   swprintf
      #define _tcslen     wcslen
      #define _tcscpy     wcscpy
      #define _tcscat     wcscat
      #define _tcsncpy    wcsncpy
      #define _tcscmp     wcscmp
      //jcfuller added
      #define _tcsicmp    wcsicmp
      #define _tcsncmp    wcsncmp
      #define _tcsnicmp   _wcsnicmp
      #define _tcsrev     _wcsrev
      //#define FltToTch    FltToWch
      #define _ttol       _wtol
      #define _ttoi       _wtoi
      #define _ttoi64     _wtoi64
      #define _gettchar getchar
      #define _ttof       _wtof
      //jcfuller added
      #define _tcschr     _wcschr
      #define Version VersionW
      #define _totupper   towupper
      #define _totlower   tolower
      #define _istspace   _iswspace
      #define _istdigit   _iswdigit
      #define _istxdigit  _iswxdigit
      #define _istalpha   _iswalpha
      #define _istalnum   _iswalnum
      #define _istcntrl   _iswcntrl
      #define _istprint   _iswprint
      #define _istgraph   _iswgraph
      #define _istlower   _iswlower
      #define _istpunct   _iswpunct
      #define _istupper   _iswupper
      #define _tsystem    tcl__wsystem
      #define _tsplitpath tcl_wsplitpath
      #define wcsstr _wcsstr
      //#define rand _rand
      //#define srand _srand
      //#define exit tcl_exit
      #define fflush tcl_fflush
      #define _fgettc fgetwc
      #define _ungettc ungetwc
      #define _TEOF WEOF
      #define _istspace   _iswspace
   #else
      typedef char        TCHAR;
      #define _T(x)       x
      #define _tmain      main
      #define _tWinMain   WinMain
      #define _tfopen     fopen
      #define _fgetts     fgets
      #define _tprintf    printf
      #define _ftprintf   fprintf
      #define _stprintf   sprintf
      #define _tcslen     strlen
      #define _tcscpy     strcpy
      #define _tcscat     strcat
      #define _tcsncpy    strncpy
      #define _tcscmp     strcmp
      //jcfuller added
      #define _tcsicmp    stricmp
     
      #define _tcsncmp    strncmp
      #define _tcsnicmp   _strnicmp
      #define _tcsrev     _strrev
      #define FltToTch    FltToCh
      #define _ttol       atol
      #define _ttoi64     _atoi64
      //jcfuller added
      #define strchr     _strchr
      #define Version VersionA
      #define _istspace   _isspace
      //#define rand _rand
      //#define srand _srand
      #define exit tcl_exit
      #define fflush tcl_fflush
      #define _tsplitpath tcl_splitpath   
      #define isspace   _isspace
      #define isdigit   _isdigit
      #define isxdigit  _isxdigit
      #define isalpha   _isalpha
      #define isalnum   _isalnum
      #define iscntrl   _iscntrl
      #define isprint   _isprint
      #define isgraph   _isgraph
      #define islower   _islower
      #define ispunct   _ispunct
      #define isupper   _isupper
      #define _atof atof
      #define _fgettc fgetc
      #define _ungettc ungetc
      #define _TEOF EOF
   #endif
#endif



James C. Fuller

Patrice,
  I think your problem might be your use of CopyMemory instead of wmemcpy in the replace function??
Aren't you copying char's instead of wchar's?

James

Patrice Terrier

James--

You are absolutly right, i forget to multiply delta by sizeof(WCHAR), as i am dealind with Unicode while BC9 is using ANSI
CopyMemory(r, p, delta*sizeof(WCHAR));

My mistake, thank you!
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com