Author Topic: FreeBASIC CWstr  (Read 32067 times)

0 Members and 3 Guests are viewing this topic.

Offline Juergen Kuehlwein

  • Full Member
  • ***
  • Posts: 129
Re: FreeBASIC CWstr
« Reply #15 on: April 10, 2018, 10:33:30 PM »
Yes, i know. But my point was, maybe it is possible to improve the existing workarounds for "LEFT/RIGHT" and to write a new one for the MID statement (not function - this already works) in order to get a consistent syntax (as far as possible, just like with the other, native string types), and not to have to resort to "special" handling for special cases (even if these are rare cases).

Your work on CWSTR is absolutly great and almost perfect, i don´t want to criticize it! My intention is to help to make it as perfect as possible NOW (i don´t want to wait until "one day" :-)).


JK

Offline José Roca

  • Administrator
  • Hero Member
  • *****
  • Posts: 2481
Re: FreeBASIC CWstr
« Reply #16 on: April 10, 2018, 11:43:41 PM »
I appreciate your suggestions, but they're flawed. We have to be very cautious when using BYREF AS WSTRING.

Code: [Select]
PRIVATE FUNCTION Leftx (BYREF cws AS CWSTR, BYVAL nChars AS INTEGER) byref as wstring

static s as cwstr

   s = LEFT(**cws, nChars)
   RETURN *cast(wstring ptr, *s)

END FUNCTION

DIM cws AS CWSTR = "12345"

print LEFTx(cws, 2) & LEFTx(cws, 3)   ' wrongly prints 1212
print LEFTx(cws, 2) & LEFTx(cws, 3) &  LEFTx(cws, 5)   ' wrongly prints 121212

And regarding MID as a statement, it will lose speed, a fatal flaw since the main reason of using MID as a statement it is because it is fast.

Offline Juergen Kuehlwein

  • Full Member
  • ***
  • Posts: 129
Re: FreeBASIC CWstr
« Reply #17 on: April 12, 2018, 12:11:59 AM »
Ok José, you got me!


The intermediate storage (which i would prefer to avoid anyway) bites me. What about this:
Code: [Select]
PRIVATE FUNCTION Leftx (BYref cws AS cwstr, BYVAL nChars AS INTEGER) as string
  function = LEFT(*cast(wSTRING PTR, cws.m_pBuffer), nChars)
END FUNCTION
according to my tests it works, can you make it fail ?


Another thing i don´t understand, is why the compiler won´t let me do this:
Code: [Select]
Function Leftx ( ByRef str As Const WString, ByVal n As Integer ) As WString

the code is taken from the help file ("Left"), but it doesn´t compile ("Expected pointer in: <this line>")


All this type casting, even with pointers, is driving me crazy. You know i have some assembler background and there a pointer is a pointer and (seemingly) non-matching types aren´t just rejected with error messages, i don´t understand. In FreeBASIC it is sometimes really frustrating to find a way to make the compiler happy.


JK

Offline José Roca

  • Administrator
  • Hero Member
  • *****
  • Posts: 2481
Re: FreeBASIC CWstr
« Reply #18 on: April 12, 2018, 01:56:29 AM »
> according to my tests it works, can you make it fail ?

Of course. Try using it with Russian, for example, instead of "12345".

Code: [Select]
PRIVATE FUNCTION Leftx (BYref cws AS cwstr, BYVAL nChars AS INTEGER) as string
  function = LEFT(*cast(wSTRING PTR, cws.m_pBuffer), nChars)
END FUNCTION

DIM cws AS CWSTR = "Дмитрий Дмитриевич Шостакович"
PRINT LEFTx(cws, 3)

Will print ???", which is the expected result since you are returning it as an ansi string.

Believe me. I did lose countless hours trying to find an acceptable solution, but since it is a bug of the compiler, the solution will be to fix the bug.

Anyway, with the current overloads, it works except with SELECT CASE LEFT/RIGHT. I didn't even know because I never have used LEFT and RIGHT with SELECT CASE. Indeed there are easy workarounds: assign it to a variable first, use MID or use **.

I have managed to get an almost total integration with FreeBasic instrinsics. It even works with files, e.g.:

Code: [Select]
DIM cws AS CWSTR = "Дмитрий Дмитриевич Шостакович"

DIM f AS LONG = FREEFILE
OPEN "test.txt" FOR OUTPUT ENCODING "utf16" AS #f
PRINT #f, cws
CLOSE #f

Offline José Roca

  • Administrator
  • Hero Member
  • *****
  • Posts: 2481
Re: FreeBASIC CWstr
« Reply #19 on: April 12, 2018, 02:00:19 AM »
Quote
Another thing i don´t understand, is why the compiler won´t let me do this:

Function Leftx ( ByRef str As Const WString, ByVal n As Integer ) As WString


A WSTRING in FB is not like a WSTRING in PB. The PB equivalent is WSTRINGZ and, of course, you can't return a WSTRINGZ or an ASCIIZ as the result of a function. The compiler is expecting AS WSTRING PTR.

Quote
the code is taken from the help file ("Left"), but it doesn´t compile ("Expected pointer in: <this line>")

It is not an example, but a prototype to document the function. It means that the native Left function will return a WSTRING, not thatyyou can use AS WSTRING as the result of your own function. Don't confuse the prototypes used to document the FB keywords with code.


« Last Edit: April 12, 2018, 02:27:21 AM by José Roca »

Offline José Roca

  • Administrator
  • Hero Member
  • *****
  • Posts: 2481
Re: FreeBASIC CWstr
« Reply #20 on: April 12, 2018, 02:05:04 AM »
BTW I don't understand why you want to make your future visual designer to generate ansi or unicode. Only unicode is needed. There is not a single advantage of making an ansi GUI. Even the latest PBWIN compiler uses unicode only.

Offline José Roca

  • Administrator
  • Hero Member
  • *****
  • Posts: 2481
Re: FreeBASIC CWstr
« Reply #21 on: April 12, 2018, 02:21:50 AM »
Quote
All this type casting, even with pointers, is driving me crazy. You know i have some assembler background and there a pointer is a pointer and (seemingly) non-matching types aren´t just rejected with error messages, i don´t understand. In FreeBASIC it is sometimes really frustrating to find a way to make the compiler happy.

FB has been written by C programmers and these guys are used to use casting in almost each line of code. This could be changed by using ANY PTR in the declares. FB uses BASIC syntax, but the declares have been prototyped to use them like with C.

« Last Edit: April 12, 2018, 02:24:24 AM by José Roca »

Offline Juergen Kuehlwein

  • Full Member
  • ***
  • Posts: 129
Re: FreeBASIC CWstr
« Reply #22 on: April 12, 2018, 07:44:54 PM »
José,

Quote
Believe me. I did lose countless hours trying to find an acceptable solution

... accepted! Nevertheless this discussion wasn´t useless (at least for me). I definitely learned something and you showed a workaround for LEFT/RIGHT - MID, which can have the same syntax for both!



Quote
I don't understand why you want to make your future visual designer to generate ansi or unicode


Well, there weren´t dynamic Unicode strings in FreeBASIC before you came. Therefore i think not many at FreeBASIC are familiar with it. If the Visual Designer produced only Unicode, many could be deterred. So the idea is to pick them up where they are (ANSI) and show and easy way to switch to Unicode. As far as possible i would like everybody to be able to have it his/her way.


Thanks a lot - i will ask questions again as they arise...


JK

Offline José Roca

  • Administrator
  • Hero Member
  • *****
  • Posts: 2481
Re: FreeBASIC CWstr
« Reply #23 on: April 12, 2018, 08:42:02 PM »
In fact, because it has casts to return either the content of the string or a pointer ro the beginning of the string data, depending on the target type, there is not need for STRPTR, which won't work anyway.

Code: [Select]
' // Populate the ListView with some data
DIM cwsTxt AS CWSTR
DIM lvi AS LVITEM
lvi.mask = LVIF_TEXT
FOR i AS LONG = 0 to 29
   lvi.iItem = i
   lvi.iSubItem = 0
   cwsTxt = "Column 0 Row " & i
   lvi.pszText = cwsTxt
   ListView_InsertItem(hListView, @lvi)
   FOR x AS LONG = 1 TO 4
      cwsTxt = "Column " & x & " Row " & i
      ListView_SetItemText(hListView, i, x, cwsTxt)
   NEXT
NEXT
« Last Edit: April 12, 2018, 08:47:48 PM by José Roca »

Offline José Roca

  • Administrator
  • Hero Member
  • *****
  • Posts: 2481
Re: FreeBASIC CWstr
« Reply #24 on: April 12, 2018, 09:01:03 PM »
Another workaround for SELECT CASE LEFT

Code: [Select]
SELECT CASE LEFT(cws.wstr, 2)

It also works for MID

Code: [Select]
MID(cws.wstr, 3, 2) = "AB"

It does the same that **, but those not familiar with pointers may prefer it:

Code: [Select]
' ========================================================================================
' Returns the string data (same as **).
' ========================================================================================
PRIVATE FUNCTION CWstr.wstr () BYREF AS WSTRING
   CWSTR_DP("CWSTR wstr - buffer: " & .WSTR(m_pBuffer))
   RETURN *cast(WSTRING PTR, m_pBuffer)
END FUNCTION
' ========================================================================================
« Last Edit: April 12, 2018, 09:17:43 PM by José Roca »

Offline José Roca

  • Administrator
  • Hero Member
  • *****
  • Posts: 2481
Re: FreeBASIC CWstr
« Reply #25 on: April 12, 2018, 09:06:40 PM »
And if someone can't live without STRPTR, instead of

Code: [Select]
lvc.pszText = cwsText

he can use

Code: [Select]
lvc.pszText = cwsText.sptr

Offline Juergen Kuehlwein

  • Full Member
  • ***
  • Posts: 129
Re: FreeBASIC CWstr
« Reply #26 on: April 12, 2018, 09:51:18 PM »
José,


i can live without "STRPTR" perfectly well, especially since i know (and i understand why) i can pass the string instead of its pointer. "MID" can be a replacement for the buggy "LEFT/RIGHT". So i can have the same syntax for both, which is my objective.

I want to present a working solution first - then i can come up with explanations, that this or that, which may look strange, isn´t due to my bad code or some shortcommings in CWStr but a known compiler error and that you must accept certain minor restrictions when using it. To my experience most of times people don´t want to hear (or even know) about things that don´t work - they want to hear about things, that work (and maybe then about how and why it works).


Thanks again,


JK

Offline Juergen Kuehlwein

  • Full Member
  • ***
  • Posts: 129
Re: Unicode
« Reply #27 on: April 13, 2018, 07:02:05 PM »
Maybe a stupid question, but how to enter russian letters in CSED? I must check "Enable unicode (UTF-8 encoding)" and then? E.g. Alt + 0411 (Numpad) should result in a cyrillic capital b. I can paste cyrillic characters, but i don´t know how to type them.


JK

Offline José Roca

  • Administrator
  • Hero Member
  • *****
  • Posts: 2481
Re: FreeBASIC CWstr
« Reply #28 on: April 13, 2018, 07:44:46 PM »
I never have tried. You have to activate cyrillic support.
See: https://www.wikihow.com/Type-Russian-Characters

Offline Juergen Kuehlwein

  • Full Member
  • ***
  • Posts: 129
Re: FreeBASIC CWstr
« Reply #29 on: April 14, 2018, 01:53:28 PM »
José,


while FreeBASIC accepts ANSI, UTF-8 and UTF-16 encoded code files as sources, PB´s compiler accepts only ANSI files, so how to embed unicode literals in code? You may append "$$", but that doesn´t allow for giving unicode insde the quotation marks. I could do something like this:

Code: [Select]
$$russian = chr$$(&H416,&H416)        -> Scintilla + PB´s IDE
w$$ = Utf8ToChr$("ФЫЙЦ")              -> Scintilla (PB´s IDE cannot display UTF-8 properly)

did i miss something ?


JK