November 28, 2020, 11:13:19 AM

Author Topic: [bmx] Format String by N [ 1+ years ago ]  (Read 407 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bmx] Format String by N [ 1+ years ago ]
« on: June 29, 2017, 12:28:39 AM »
Title : Format String
Author : N
Posted : 1+ years ago

Description : This is a fairly simple FormatString function - it takes in a format string and an array of objects and returns a string with string representations of those object for every insertion found.  It's not really proper formatting, unfortunately, but at least it works for my purposes.

Insertions in the format string are marked by <index>.  All indices are one-based unsigned integers.  Indices smaller than 1 and larger than the number of objects passed will fail an assertion, and that will probably bring your application to a screeching halt.  You can escape an insertion point using another .

For example:
Code: [Select]
' Standard insertion points
Print FormatString("1 2 03 ", [Object("Foo"), Object(Null), Object("Wimbleton")]) ' => Foo Null Wimbleton

' Escaped insertion points
Print FormatString("\1 \2 \003", [Object("Foo"), Object(Null), Object("Wimbleton")]) ' => 1 2 03

' Slightly practical example
Print FormatString("TTypeID.ForName(~q1~q).FindMethod(~q2~q).Invoke(3, args)", ["TList", "AddLast", "obj"]) ' => TTypeId.ForName("TList").FindMethod("AddLast").Invoke(obj, args)


Code :
Code: BlitzMax
  1. SuperStrict
  2.  
  3. Function FormatStringWithList$(format$, list:TList)
  4.         Local arr:Object[]
  5.         If list Then
  6.                 arr = list.ToArray()
  7.         EndIf
  8.         Return FormatString(format, arr)
  9. End Function
  10.  
  11. Function FormatString$(format$, objects:Object[])
  12.         Const CHAR_0% = 48
  13.         Const CHAR_9% = 57
  14.         Const CHAR_SLASH% = 92
  15.        
  16.         Local strings:String[objects.Length]
  17.        
  18.         For Local index:Int = 0 Until objects.Length
  19.                 If objects[index] Then
  20.                         strings[index] = objects[index].ToString()
  21.                 Else
  22.                         strings[index] = "Null"
  23.                 EndIf
  24.         Next
  25.        
  26.         Local numberIndices:Int[] = [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]
  27.         Local numberLengths:Int[16]
  28.         Local numbers:Int[16]
  29.         Local numberIndex:Int = 0
  30.         Local escape:Int = False
  31.         Local length:Int = 0
  32.         Local char:Int
  33.        
  34.         For Local index:Int = 0 Until format.Length
  35.                 char = format[index]
  36.                
  37.                 If escape Then
  38.                         If CHAR_0 <= char And char <= CHAR_9 Then
  39.                                 If numberLengths[numberIndex] = 0 Then
  40.                                         numberIndices[numberIndex] = index-1
  41.                                 EndIf
  42.                                
  43.                                 char :- CHAR_0
  44.                                 numbers[numberIndex] :* 10
  45.                                 numbers[numberIndex] :+ char
  46.                                 numberLengths[numberIndex] :+ 1
  47.                                 Continue
  48.                         ElseIf numberIndices[numberIndex] <> -1 Then
  49.                                 numbers[numberIndex] :- 1
  50.                                 Assert numbers[numberIndex] >= 0 And numbers[numberIndex] < strings.Length ..
  51.                                         Else "FormatString: Index out of range: index must be >= 1 and <= objects.Length"
  52.                                 length :+ strings[numbers[numberIndex]].Length
  53.                                 numberIndex :+ 1
  54.                                 escape = False
  55.                         EndIf
  56.                 EndIf
  57.                
  58.                 If char = CHAR_SLASH Then
  59.                         If Not escape Then
  60.                                 If numberIndex >= numbers.Length Then
  61.                                         numbers = numbers[..numbers.Length*2]
  62.                                         numberLengths = numberLengths[..numbers.Length]
  63.                                         numberIndices = numberIndices[..numbers.Length]
  64.                                 EndIf
  65.                                 escape = True
  66.                                 Continue
  67.                         Else
  68.                                 escape = False
  69.                         EndIf
  70.                 EndIf
  71.                
  72.                 length :+ 1
  73.         Next
  74.        
  75.         If escape And numberIndices[numberIndex] <> -1 Then
  76.                 numbers[numberIndex] :- 1
  77.                 length :+ strings[numbers[numberIndex]].Length
  78.         EndIf
  79.        
  80.         Local buffer:Short Ptr = Short Ptr MemAlloc(length * 2)
  81.         Local p:Short Ptr = buffer
  82.        
  83.         numberIndex = 0
  84.         escape = False
  85.         For Local index:Int = 0 Until format.Length
  86.                 If index = numberIndices[numberIndex] Then
  87.                         index :+ numberLengths[numberIndex]
  88.                         Local innerString$ = strings[numbers[numberIndex]]
  89.                         For Local innerStringIndex:Int = 0 Until innerString.Length
  90.                                 p[0] = innerString[innerStringIndex]
  91.                                 p :+ 1
  92.                         Next
  93.                         numberIndex :+ 1
  94.                         Continue
  95.                 ElseIf Not escape And format[index] = CHAR_SLASH Then
  96.                         escape = True
  97.                         Continue
  98.                 EndIf
  99.                 escape = False
  100.                
  101.                 p[0] = format[index]
  102.                 p :+ 1
  103.         Next
  104.        
  105.         Local output$ = String.FromShorts(buffer, length)
  106.         MemFree(buffer)
  107.         Return output
  108. End Function


Comments : none...

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal