Code archives/Miscellaneous/Format String
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
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: ' Standard insertion points Print FormatString("\1 \2 \003 ", [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 \003 ' Slightly practical example Print FormatString("TTypeID.ForName(~q\1~q).FindMethod(~q\2~q).Invoke(\3, args)", ["TList", "AddLast", "obj"]) ' => TTypeId.ForName("TList").FindMethod("AddLast").Invoke(obj, args) | |||||
SuperStrict Function FormatStringWithList$(format$, list:TList) Local arr:Object[] If list Then arr = list.ToArray() EndIf Return FormatString(format, arr) End Function Function FormatString$(format$, objects:Object[]) Const CHAR_0% = 48 Const CHAR_9% = 57 Const CHAR_SLASH% = 92 Local strings:String[objects.Length] For Local index:Int = 0 Until objects.Length If objects[index] Then strings[index] = objects[index].ToString() Else strings[index] = "Null" EndIf Next Local numberIndices:Int[] = [-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1] Local numberLengths:Int[16] Local numbers:Int[16] Local numberIndex:Int = 0 Local escape:Int = False Local length:Int = 0 Local char:Int For Local index:Int = 0 Until format.Length char = format[index] If escape Then If CHAR_0 <= char And char <= CHAR_9 Then If numberLengths[numberIndex] = 0 Then numberIndices[numberIndex] = index-1 EndIf char :- CHAR_0 numbers[numberIndex] :* 10 numbers[numberIndex] :+ char numberLengths[numberIndex] :+ 1 Continue ElseIf numberIndices[numberIndex] <> -1 Then numbers[numberIndex] :- 1 Assert numbers[numberIndex] >= 0 And numbers[numberIndex] < strings.Length .. Else "FormatString: Index out of range: index must be >= 1 and <= objects.Length" length :+ strings[numbers[numberIndex]].Length numberIndex :+ 1 escape = False EndIf EndIf If char = CHAR_SLASH Then If Not escape Then If numberIndex >= numbers.Length Then numbers = numbers[..numbers.Length*2] numberLengths = numberLengths[..numbers.Length] numberIndices = numberIndices[..numbers.Length] EndIf escape = True Continue Else escape = False EndIf EndIf length :+ 1 Next If escape And numberIndices[numberIndex] <> -1 Then numbers[numberIndex] :- 1 length :+ strings[numbers[numberIndex]].Length EndIf Local buffer:Short Ptr = Short Ptr MemAlloc(length * 2) Local p:Short Ptr = buffer numberIndex = 0 escape = False For Local index:Int = 0 Until format.Length If index = numberIndices[numberIndex] Then index :+ numberLengths[numberIndex] Local innerString$ = strings[numbers[numberIndex]] For Local innerStringIndex:Int = 0 Until innerString.Length p[0] = innerString[innerStringIndex] p :+ 1 Next numberIndex :+ 1 Continue ElseIf Not escape And format[index] = CHAR_SLASH Then escape = True Continue EndIf escape = False p[0] = format[index] p :+ 1 Next Local output$ = String.FromShorts(buffer, length) MemFree(buffer) Return output End Function |
Comments
None.
Code Archives Forum