James
Do you have a BC9 example showing how the PB's REPLACE statement is translated to WCHAR ?
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
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;
}
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,
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
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
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!