Skip to content

Commit

Permalink
C backend: Fix wstring literals when wstring is FB_DATATYPE_UBYTE but…
Browse files Browse the repository at this point in the history
… gcc uses a 4-byte wchar_t

This fixes wstrings on android, where I am using 1-byte wstring instead of
4-byte, to support older Android versions.

This is only necessary because our wchar_t size on android doesn't match
gcc's size. Which is the case because early versions of Android don't support
wchar_t: all wchar_t functions in the standard library actually redirect to
the 8-bit versions. Starting with Android 2.3 wchar_t became 32-bit even
though widechar support is still partial, even today, and not standards
compliant.
  • Loading branch information
rversteegen authored and jayrm committed Jan 2, 2024
1 parent b94c468 commit a1ffde6
Showing 1 changed file with 17 additions and 4 deletions.
21 changes: 17 additions & 4 deletions src/compiler/ir-hlc.bas
Expand Up @@ -2224,11 +2224,19 @@ private sub hBuildWstrLit _

dim as integer ch = any
dim as integer wcharsize = any
dim as zstring ptr strstart = any

'' (ditto)

ln += "L"""
wcharsize = typeGetSize( FB_DATATYPE_WCHAR )
'' On android wstring is 1 byte but C wide strings/chars are 4 bytes, so don't use them
if( wcharsize = 1 ) then
strstart = @""""
else
strstart = @"L"""
end if

ln += *strstart

'' Don't bother emitting the null terminator explicitly - gcc will add
'' it automatically already
Expand All @@ -2238,7 +2246,7 @@ private sub hBuildWstrLit _
if( hCharNeedsEscaping( ch, asc( """" ) ) ) then
ln += $"\x" + hex( ch, wcharsize * 2 )
if( hIsValidHexDigit( (*w)[i+1] ) ) then
ln += """ L"""
ln += """ " + *strstart
end if
elseif( ch = asc( "?" ) ) then
ln += "?"
Expand All @@ -2248,7 +2256,7 @@ private sub hBuildWstrLit _
case asc( "=" ), asc( "/" ), asc( "'" ), _
asc( "(" ), asc( ")" ), asc( "!" ), _
asc( "<" ), asc( ">" ), asc( "-" )
ln += """ L"""
ln += """ " + *strstart
end select
end if
else
Expand Down Expand Up @@ -3860,7 +3868,12 @@ private sub _emitVarIniWstr _
ctx.varini += ", "
end if

ctx.varini += "L'"
'' On android wstring is 1 byte but C wide strings/chars are 4 bytes, so don't use them
if( wcharsize = 1 ) then
ctx.varini += "'"
else
ctx.varini += "L'"
end if

ch = (*literal)[i]

Expand Down

0 comments on commit a1ffde6

Please sign in to comment.