Apache OpenOffice (AOO) Bugzilla – Issue 128533
The BASIC function Str inserts a space before negative numbers
Last modified: 2023-01-21 08:44:13 UTC
AOO Help on the Str function: "The Str function converts a numeric variable, or the result of a calculation into a string. Negative numbers are preceded by a minus sign. Positive numbers are preceded by a space (instead of the plus sign)." So for a value of 1 and -1 the Str function shall return, respectively, ' 1' and '-1' (single quotes here are not part of the returned strings). Nonetheless the following code sub test_Str MsgBox "'" & Str(1) & "'" & Chr(13) &_ "'" & Str(-1) & "'" end sub displays: ' 1' ' -1' Only with Option VBASupport 1 or CompatibilityMode(True) one gets the _expected_ value, i.e. ' 1' and '-1' And one more inaccuracy - AOO Help on the Format function: Syntax: Format (Number [, Format As String]) Format: String that specifies the format code for the number. If Format is omitted, the Format function works like the Str function. Thus Format(Number) should yield the same result as Str(Number) The following code: sub test_Format MsgBox "'" & Format(1) & "'" & Chr(13) &_ "'" & Format(-1) & "'" end sub shows: '1' '-1'
Our StarBasic implementation is in main/basic. In there, built-in functions like Str() are declared with the form RTLFUNC(Str), and be found with: $ grep RTLFUNC\(Str * -R which gives, among others: runtime/methods.cxx:RTLFUNC(Str) where we see what it does: ---snip--- 1573 RTLFUNC(Str) 1574 { 1575 (void)pBasic; 1576 (void)bWrite; 1577 1578 if ( rPar.Count() < 2 ) 1579 StarBASIC::Error( SbERR_BAD_ARGUMENT ); 1580 else 1581 { 1582 String aStr; 1583 SbxVariableRef pArg = rPar.Get( 1 ); 1584 pArg->Format( aStr ); 1585 1586 // Numbers start with a space 1587 if( pArg->IsNumericRTL() ) 1588 { 1589 // Kommas durch Punkte ersetzen, damit es symmetrisch zu Val ist! 1590 aStr.SearchAndReplace( ',', '.' ); 1591 1592 SbiInstance* pInst = pINST; 1593 bool bCompatibility = ( pInst && pInst->IsCompatibility() ); 1594 if( bCompatibility ) 1595 { 1596 xub_StrLen nLen = aStr.Len(); 1597 1598 const sal_Unicode* pBuf = aStr.GetBuffer(); 1599 1600 bool bNeg = ( pBuf[0] == '-' ); 1601 sal_uInt16 iZeroSearch = 0; 1602 if( bNeg ) 1603 iZeroSearch++; 1604 1605 sal_uInt16 iNext = iZeroSearch + 1; 1606 if( pBuf[iZeroSearch] == '0' && nLen > iNext && pBuf[iNext] == '.' ) 1607 { 1608 aStr.Erase( iZeroSearch, 1 ); 1609 pBuf = aStr.GetBuffer(); 1610 } 1611 if( !bNeg ) 1612 aStr.Insert( ' ', 0 ); 1613 } 1614 else 1615 aStr.Insert( ' ', 0 ); 1616 } 1617 rPar.Get(0)->PutString( aStr ); 1618 } 1619 } ---snip--- Put a breakpoint on SbRtl_Str (which is what RTLFUNC(Str) mangles the name to), and debugging, line 1587 is true, and line 1594 is false, so a space is unconditionally appended in line 1615. Maybe line 1615 should check for bNeg before adding the space, like lines 1611-1612 do? As for the relationship between Str() and Format(), note that line 1584 calls pArg->Format(). The built-in Format() function in RTLFUNC(Format) also calls the Format() method on its arg. These end up in SbxValue::Format() of main/basic/source/sbx/sbxscan.cxx, and end up converting the double to a string. Yet Str() adds the space after calling Format(). So it's not accurate to say "the Format function works like the Str function".
Thank you, damjan, for the code pointer and analysis. > Maybe line 1615 should check for bNeg before adding the space, > like lines 1611-1612 do? Quite recently I came across a bug report submitted to LibreOffice Bugzilla that is similar to my report. tdf#146590 "Basic's Str function adding unnecessary blank space before negative numbers" https://bugs.documentfoundation.org/show_bug.cgi?id=146590 Please take a look at the comment therein (I have no idea whether it might bear any relevance to OpenOffice).