source: trunk/Include/Classes/ActiveBasic/Strings/SPrintF.ab @ 383

Last change on this file since 383 was 383, checked in by イグトランス (egtra), 16 years ago

SPrintf関数の実装

File size: 38.5 KB
Line 
1'Classes/ActiveBasic/Strings/SPrintF.ab
2
3Namespace ActiveBasic
4Namespace Strings
5
6Namespace Detail
7
8/*!
9@brief  浮動小数点数を文字列化する低水準な関数。符号、指数、仮数に分けて出力。
10@author Egtra
11@date   2007/09/18
12@param[in]  x   文字列化する浮動小数点数
13@param[out] e   指数
14@param[out] sign    符号
15@return 仮数
16仮数は1の位から下へ17桁で、小数点を含まない。そのため、誤差を無視すればVal(仮数) * 10 ^ (e - 17) = Abs(x)が成り立つ。
17
18xに無限大、非数を渡した場合の動作は未定義。
19*/
20Function FloatToChars(x As Double, ByRef e As Long, ByRef sign As Boolean) As String
21    Imports System
22
23    '0を弾く
24    If x = 0 Then
25        If GetQWord(VarPtr(x) As *QWord) And &h8000000000000000 Then
26            sign = True
27        Else
28            sign = False
29        End If
30
31        e = 0
32        FloatToChars = "00000000000000000"
33        Exit Function
34    End If
35
36    '符号の判断(同時に符号を取り除く)
37    If x < 0 Then
38        sign = True
39        x = -x
40    Else
41        sign = False
42    End If
43
44    '1e16 <= x < 1e17へ正規化
45    '(元のx) = (正規化後のx) ^ (d - 17)である。
46    Dim d = Math.Floor(Math.Log10(x)) As Long
47    If d < 16 Then
48        x *= ipow(10, +17 - d)
49    ElseIf d > 16 Then
50        x /= ipow(10, -17 + d)
51    End If
52
53    '補正
54    While x < 1e16
55        x *= 10
56        d--
57    Wend
58    While x >= 1e17
59        x /= 10
60        d++
61    Wend
62
63    d--
64    e = d
65
66    FloatToChars = FormatIntegerLU((x As Int64) As QWord, 17, 0, None)
67End Function
68
69/*!
70@brief  書式化関数群で使用するフラグ。
71@author Egtra
72@date   2007/09/18
73*/
74Const Enum FormatFlags
75    '! 何も指定がない。
76    None = &h0
77    /*!
78    符号、+。符号付変換[diAaEeFfGg]のとき、正の値でも符号を付ける。
79    AdjustFieldWidthの仕様から、Format関数郡内からAdjustFieldWidthにかけて、
80    単に数値が符号付である(負の値である)ことを示す意味でも用いられる。
81    */
82    Sign = &h1
83    /*! 空白、空白文字。
84    符号付変換[diAaEeFfGg]のとき、正の値ならば符号分の空白を開ける。Signが立っているときには無視される。
85    */
86    Blank = &h2
87    /*! ゼロ、0。
88    [diouXxAaEeFfGg]で、フィールドの空きを0で埋める。leftが立っているときには無視される。
89    */
90    Zero = &h4
91    '! 左揃え、-。フィールド内で左揃えにする。
92    Left = &h8
93    /*! 代替表記、#。
94    <ul>
95        <li>[OoXx]では、値が0でない場合、先頭に0、0xを付ける。</ul>
96        <li>[AaEeFfGg]では、精度0でも小数点を付ける。</ul>
97        <li>[Gg]では、それに加え、小数部末尾の0の省略を行わないようにする。</ul>
98    </ul>
99    */
100    Alt = &h10
101    '! 大文字。使用するアルファベットを大文字にする。[aefgx]を[AEFGX]化する。
102    Cap = &h20
103
104    '!BASIC接頭辞。&h, &oなど。
105    BPrefix = &h40
106
107    /*!
108    内部処理用に予約。
109    @note   Minusとして使用されている。
110    */
111    Reserved = &h80000000
112End Enum
113
114/*!
115@brief  浮動小数点数をprintfの%e, %E(指数形式、十進法)相当の変換で文字列化する関数。
116@author Egtra
117@date   2007/09/18
118@param[in] x    文字列化する浮動小数点数値。
119@param[in] precision    精度。小数点以下の桁数。DWORD_MAXのとき、指定なしとして既定値6となる。
120@param[in] field    フィールド幅。
121@param[in] flags    書式フラグ。
122@return xの文字列表現
123
124@todo   他の実装での末尾桁の扱いを調べる(このコードでは何もしていないので切捨となっている)。
125*/
126Function FormatFloatE(x As Double, precision As DWord, field As DWord, flags As FormatFlags) As String
127    If precision = DWORD_MAX Then
128        precision = 6
129    End If
130
131    Dim e As Long, negative As Boolean
132    Dim s = FloatToChars(x, e, negative)
133    Dim sb = FormatFloatE_Base(s, negative, precision, flags)
134    FormatFloatE_Exponent(sb, e, flags)
135    AdjustFieldWidth(sb, field, flags)
136    FormatFloatE = sb.ToString()
137End Function
138
139/**
140@brief  FormatFloatEの符号・基数部の出力用。
141@author Egtra
142@date   2007/10/27
143*/
144Function FormatFloatE_Base(s As String, negative As Boolean, precision As DWord, ByRef flags As FormatFlags) As System.Text.StringBuilder
145    FormatFloatE_Base = New System.Text.StringBuilder
146    With FormatFloatE_Base
147        AppendSign(FormatFloatE_Base, negative, flags)
148
149        .Append(s[0])
150
151        If (flags And Alt) Or precision > 0 Then
152            .Append(".")
153            Dim outputLen = s.Length - 1
154            If outputLen >= precision Then
155                .Append(s, 1, precision)
156            Else 'sで用意された桁が指定された精度より少ないとき
157                .Append(s, 1, outputLen)
158                .Append(&h30 As StrChar, precision - outputLen) '足りない桁は0埋め
159            End If
160        End If
161    End With
162End Function
163
164/**
165@brief  FormatFloatEの指数部の出力用。
166@author Egtra
167@date   2007/10/27
168*/
169Sub FormatFloatE_Exponent(buf As System.Text.StringBuilder, e As Long, flags As FormatFlags)
170    With buf
171        If flags And Cap Then
172            .Append("E")
173        Else
174            .Append("e")
175        End If
176        .Append(FormatIntegerD(e, 2, 0, Sign Or Zero))
177    End With
178End Sub
179
180/*!
181@brief  浮動小数点数をprintfの%f(小数形式、十進法)相当の変換で文字列化する関数。
182@author Egtra
183@date   2007/10/23
184@param[in]  x   文字列化する浮動小数点数値。
185@param[in]  precision   精度。小数点以下の桁数。DWORD_MAXのとき、指定なしとして既定値6となる。
186@param[in]  field   フィールド幅。
187@param[in]  flags   書式フラグ。
188@return xの文字列表現
189*/
190Function FormatFloatF(x As Double, precision As DWord, field As DWord, flags As FormatFlags) As String
191    If precision = DWORD_MAX Then
192        precision = 6
193    End If
194
195    Dim e As Long, negative As Boolean
196    Dim s = FloatToChars(x, e, negative)
197    Dim sb = FormatFloatF_Core(s, e, negative, precision, flags)
198    AdjustFieldWidth(sb, field, flags)
199    FormatFloatF = sb.ToString()
200End Function
201
202/**
203@author Egtra
204@date   2007/10/27
205*/
206Function FormatFloatF_Core(s As String, e As Long, negative As Boolean, precision As DWord, ByRef flags As FormatFlags) As System.Text.StringBuilder
207    FormatFloatF_Core = New System.Text.StringBuilder
208    With FormatFloatF_Core
209        AppendSign(FormatFloatF_Core, negative, flags)
210
211        Dim intPartLen = e + 1
212        Dim outputDigit = 0 As DWord
213        If intPartLen >= 17 Then
214            '有効桁が全て整数部に収まる場合
215            .Append(s)
216            .Append(&h30 As StrChar, intPartLen - 17)
217            outputDigit = 17
218        ElseIf intPartLen > 0 Then
219            '有効桁の一部が整数部にかかる場合
220            .Append(s, 0, intPartLen)
221            outputDigit = intPartLen
222        Else
223            '有効桁が全く整数部にかからない場合
224            .Append(&h30 As StrChar)
225        End If
226
227        If precision > 0 Or (flags And Alt) Then
228            .Append(".")
229
230            Dim lastDigit = s.Length - outputDigit
231            If lastDigit >= precision Then '変換して得られた文字列の桁数が精度以上ある場合
232                Dim zeroDigit = 0
233                If intPartLen < 0 Then
234                    '1.23e-4 = 0.000123のように指数が負のため小数点以下に0が続く場合
235                    zeroDigit = System.Math.Min(-intPartLen As DWord, precision)
236                    .Append(&h30 As StrChar, zeroDigit As Long)
237                End If
238                .Append(s, outputDigit, (precision - zeroDigit) As Long)
239            Else
240                .Append(s, outputDigit, lastDigit)
241                .Append(&h30 As StrChar, (precision - lastDigit) As Long) '残りの桁は0埋め
242            End If
243        End If
244    End With
245End Function
246
247/*!
248@brief  浮動小数点数をprintfの%g, %G(小数・指数、十進法)相当の変換で文字列化する関数。
249@author Egtra
250@date   2007/10/23
251@param[in]  x   文字列化する浮動小数点数値。
252@param[in]  precision   精度。小数点以下の桁数。DWORD_MAXまたは0のとき、指定なしとして既定値6となる。
253@param[in]  field   フィールド幅。
254@param[in]  flags   書式フラグ。
255@return xの文字列表現
256@todo   下位桁の扱いの調査。
257*/
258Function FormatFloatG(x As Double, precision As DWord, field As DWord, flags As FormatFlags) As String
259    'GではE/Fと違い整数部も有効桁数に数えるのでその分を引いておく。
260    If precision = DWORD_MAX Or precision = 0 Then
261        precision = 5
262    Else
263        precision--
264    End If
265
266    Dim e As Long, negative As Boolean
267    Dim s = FloatToChars(x, e, negative)
268
269    Dim sb = Nothing As System.Text.StringBuilder
270
271    If -5 < e And e < precision Then
272        sb = FormatFloatF_Core(s, e, negative, -e + precision, flags)
273        FormatFloatG_RemoveLowDigit(sb, flags)
274    Else
275        sb = FormatFloatE_Base(s, negative, precision, flags)
276        FormatFloatG_RemoveLowDigit(sb, flags)
277        FormatFloatE_Exponent(sb, e, flags)
278    End If
279
280    AdjustFieldWidth(sb, field, flags)
281    FormatFloatG = sb.ToString()
282End Function
283
284/*!
285@brief  FormatFloatG/A用の小数点以下末尾の0を削除するルーチン
286@author Egtra
287@date   2007/10/27
288@param[in, out] sb 文字列バッファ
289@param[in]  flags フラグ
290flagsでAltが立っているとき、この関数は何もしない。
291*/
292Sub FormatFloatG_RemoveLowDigit(sb As System.Text.StringBuilder, flags As FormatFlags)
293    Imports ActiveBasic.Strings
294   
295    Dim count = sb.Length
296    If (flags And Alt) = 0 Then
297        Dim point = ChrFind(StrPtr(sb), count As SIZE_T, Asc("."))
298        If point = -1 Then
299            Debug
300        End If
301
302        Dim i As Long
303        For i = count - 1 To point + 1 Step -1
304            If sb[i] <> &h30 Then
305                Exit For
306            End If
307        Next
308        If i <> point Then
309            i++
310        End If
311        sb.Length = i
312    End If
313End Sub
314
315/*!
316@brief  浮動小数点数をprintfの%a, %A(指数形式、十六進法)相当の変換で文字列化する関数。
317@author Egtra
318@date   2007/09/18
319@param[in] x    文字列化する浮動小数点数値。
320@param[in] precision    精度。小数点以下の桁数。DWORD_MAXのとき、指定なしとして既定値13となる。
321@param[in] field    フィールド幅。
322@param[in] flags    書式フラグ。
323@return xの文字列表現
324
325C99では、末尾の0を取り除いても良いとあるので、
326このルーチンでは取り除くことにしている。
327*/
328Function FormatFloatA(x As Double, precision As DWord, field As DWord, flags As FormatFlags) As String
329    If precision = DWORD_MAX Then
330        precision = 13
331    End If
332
333    Dim pqw = VarPtr(x) As *QWord
334
335    Dim sb = New System.Text.StringBuilder
336    With sb
337        Dim sign = (GetQWord(pqw) And &H8000000000000000) As Boolean
338        pqw[0] And= &h7fffffffffffffff
339
340        AppendSign(sb, sign, flags)
341
342        If flags And BPrefix Then
343            .Append("&H")
344        Else
345            .Append("0X")
346        End If
347
348        Dim biasedExp = (GetQWord(pqw) >> 52) As DWord And &h7FF
349        Dim exp As Long
350        If biasedExp = 0 Then
351            If GetQWord(pqw) <> 0 Then
352                exp = -1022 '非正規化数への対応
353            Else
354                exp = 0
355            End If
356            .Append("0")
357        Else
358            exp = biasedExp - 1023
359            .Append("1")
360        End If
361
362        If precision > 0 Or (flags And Alt) Then
363            .Append(".")
364            Dim base = FormatIntegerLX(GetQWord(pqw) And &h000fffffffffffff, 13, 0, flags And Cap)
365            Dim diff = precision - 13 As Long
366            If diff <= 0 Then
367                .Append(Left$(base, precision))
368            Else
369                .Append(base).Append(&h30, diff)
370            End If
371        End If
372
373        FormatFloatG_RemoveLowDigit(sb, flags)
374
375        .Append("P")
376        .Append(FormatIntegerD(exp, 1, 0, Sign))
377       
378        FormatFloatA = .ToString()
379    End With
380
381    If (flags And Cap) = 0 Then
382        FormatFloatA = FormatFloatA.ToLower()
383    End If
384End Function
385
386/*!
387@brief 先頭に符号もしくはその分の空白を出力する。FormatFloat用。
388@author Egtra
389@date 2007/10/23
390@param[in, out] sb  出力先
391@param[in] negative 符号
392@param[in, out] flags   フラグ。negative = Trueなら、Signを立てて返す。
393*/
394Sub AppendSign(sb As System.Text.StringBuilder, negative As Boolean, ByRef flags As FormatFlags)
395    With sb
396        If negative Then
397            .Append("-")
398            flags Or= Sign
399        Else
400            If flags And Sign Then
401                .Append("+")
402            ElseIf flags And Blank Then
403                .Append(" ")
404            End If
405        End If
406    End With
407End Sub
408
409/*!
410@brief  DWordの最大値4294967295の文字数 - 1。FormatIntegerU内で使用。
411@author Egtra
412@date   2007/09/18
413*/
414Const MaxSizeU = 9
415
416/*!
417@brief  符号無し整数をprintfの%u(十進法表現)相当の変換で文字列化する関数。
418@author Egtra
419@date   2007/09/18
420@param[in]  x   文字列化する整数値。
421@param[in]  d   精度、最小限表示される桁数。DWORD_MAXのとき、指定なしとして、既定値1となる。
422@param[in]  field   フィールド幅。
423@param[in]  flags   書式フラグ。
424@return xの文字列表現
425*/
426Function FormatIntegerU(x As DWord, d As DWord, field As DWord, flags As FormatFlags) As String
427    Return FormatIntegerEx(TraitsIntegerU[0], x, d, field, flags And (Not (Sign Or Blank)))
428End Function
429
430/*!
431@brief  FormatIntegerUのQWord版
432@author Egtra
433@date   2007/10/26
434*/
435Function FormatIntegerLU(x As QWord, d As DWord, field As DWord, flags As FormatFlags) As String
436    Return FormatIntegerEx(TraitsIntegerU[1], x, d, field, flags And (Not (Sign Or Blank)))
437End Function
438
439/*!
440@brief  符号有り整数をprintfの%d(十進法表現)相当の変換で文字列化する関数。
441@author Egtra
442@date   2007/10/13
443@param[in]  x   文字列化する整数値。
444@param[in]  d   精度、最小限表示される桁数。DWORD_MAXのとき、指定なしとして、既定値1となる。
445@param[in]  field   フィールド幅。
446@param[in]  flags   書式フラグ。
447@return xの文字列表現
448*/
449Function FormatIntegerD(x As Long, d As DWord, field As DWord, flags As FormatFlags) As String
450    Return FormatIntegerEx(TraitsIntegerD[0], (x As Int64) As QWord, d, field, flags)
451End Function
452
453/*!
454@brief  FormatIntegerDのInt64版
455@author Egtra
456@date   2007/10/26
457*/
458Function FormatIntegerLD(x As Int64, d As DWord, field As DWord, flags As FormatFlags) As String
459    Return FormatIntegerEx(TraitsIntegerD[1], x As QWord, d, field, flags)
460End Function
461
462/*!
463@author Egtra
464@date   2007/10/26
465*/
466Dim TraitsIntegerU[1] As IntegerConvertTraits
467With TraitsIntegerU[0]
468    .Convert = AddressOf(IntegerU_Convert)
469    .Prefix = AddressOf(IntegerU_Prefix)
470    .MaxSize = MaxSizeU
471End With
472
473With TraitsIntegerU[1]
474    .Convert = AddressOf(IntegerLU_Convert)
475    .Prefix = AddressOf(IntegerU_Prefix)
476    .MaxSize = MaxSizeLU
477End With
478
479/*!
480@author Egtra
481@date   2007/10/28
482*/
483Dim TraitsIntegerD[1] As IntegerConvertTraits
484With TraitsIntegerD[0]
485    .Convert = AddressOf(IntegerD_Convert)
486    .Prefix = AddressOf(IntegerD_Prefix)
487    .MaxSize = MaxSizeU
488End With
489
490With TraitsIntegerD[1]
491    .Convert = AddressOf(IntegerLD_Convert)
492    .Prefix = AddressOf(IntegerD_Prefix)
493    .MaxSize = MaxSizeLU
494End With
495
496/*!
497@brief  負数を表すフラグ。FormatIntegerD, LDからIntegerDU_Prefixまでの内部処理用。
498@author Egtra
499@date   2007/10/26
500*/
501Const Minus = Reserved
502
503/*!
504@author Egtra
505@date   2007/10/26
506*/
507Function IntegerU_Convert(buf As *StrChar, xq As QWord, flags As FormatFlags) As DWord
508    Dim x = xq As DWord
509    Dim i = MaxSizeU
510    While x <> 0
511        buf[i] = (x As Int64 Mod 10 + &h30) As StrChar 'Int64への型変換は#117対策
512        x \= 10
513        i--
514    Wend
515    Return i
516End Function
517
518/*!
519@brief  IntegerU_ConvertのQWord版
520@author Egtra
521@date   2007/10/26
522@bug    #117のため、現在Int64の最大値を超える値を正しく処理できない。
523*/
524Function IntegerLU_Convert(buf As *StrChar, x As QWord, flags As FormatFlags) As DWord
525    Dim i = MaxSizeLU
526    While x <> 0
527        buf[i] = (x As Int64 Mod 10 + &h30) As StrChar 'Int64への型変換は#117対策
528        x \= 10
529        i--
530    Wend
531    Return i
532End Function
533
534/*!
535@author Egtra
536@date   2007/10/26
537*/
538Function IntegerU_Prefix(x As QWord, flags As FormatFlags) As String
539End Function
540
541/*!
542@author Egtra
543@date   2007/10/28
544*/
545Function IntegerD_Convert(buf As *StrChar, xq As QWord, flags As FormatFlags) As DWord
546    Return IntegerU_Convert(buf, Abs((xq As DWord) As Long) As DWord, flags)
547End Function
548
549/*!
550@brief  IntegerD_ConvertのInt64版
551@author Egtra
552@date   2007/10/28
553*/
554Function IntegerLD_Convert(buf As *StrChar, x As QWord, flags As FormatFlags) As DWord
555    Return IntegerLU_Convert(buf, Abs(x As Int64) As QWord, flags)
556End Function
557
558/*!
559@author Egtra
560@date   2007/10/28
561*/
562Function IntegerD_Prefix(x As QWord, flags As FormatFlags) As String
563    If (x As Int64) < 0 Then
564        IntegerD_Prefix = "-"
565    ElseIf flags And Sign Then
566        IntegerD_Prefix = "+"
567    ElseIf flags And Blank Then
568        IntegerD_Prefix = " "
569    End If
570End Function
571
572/*!
573@brief  DWordの最大値の八進法表現37777777777の文字数 - 1 + 1。IntegerO_Convert内で使用。
574@author Egtra
575@date   2007/10/19
576上の式で1を加えているのは、八進接頭辞の分。
577*/
578Const MaxSizeO = 11
579
580/*!
581@brief  QWordの最大値の八進法表現1777777777777777777777の文字数 - 1 + 1。IntegerO_Convert内で使用。
582@author Egtra
583@date   2007/10/26
584上の式で1を加えているのは、八進接頭辞の分。
585*/
586Const MaxSizeLO = 22
587
588/*!
589@author Egtra
590@date   2007/10/22
591*/
592Dim TraitsIntegerO[1] As IntegerConvertTraits
593With TraitsIntegerO[0]
594    .Convert = AddressOf(IntegerO_Convert)
595    .Prefix = AddressOf(IntegerO_Prefix)
596    .MaxSize = MaxSizeO
597End With
598
599With TraitsIntegerO[1]
600    .Convert = AddressOf(IntegerLO_Convert)
601    .Prefix = AddressOf(IntegerO_Prefix)
602    .MaxSize = MaxSizeLO
603End With
604
605/*!
606@brief  符号無し整数をprintfの%o(八進法表現)相当の変換で文字列化する関数。
607@author Egtra
608@date   2007/10/19
609@param[in]  x   文字列化する整数値。
610@param[in]  d   精度、最小限表示される桁数。DWORD_MAXのとき、指定なしとして、既定値1となる。
611@param[in]  field   フィールド幅。
612@param[in]  flags   書式フラグ。
613@return xの文字列表現
614*/
615Function FormatIntegerO(x As DWord, d As DWord, field As DWord, flags As FormatFlags) As String
616    Return FormatIntegerEx(TraitsIntegerO[0], x, d, field, flags)
617End Function
618
619/*!
620@brief  FormatIntegerOのQWord版。
621@author Egtra
622@date   2007/10/26
623*/
624Function FormatIntegerLO(x As QWord, d As DWord, field As DWord, flags As FormatFlags) As String
625    Return FormatIntegerEx(TraitsIntegerO[1], x, d, field, flags)
626End Function
627
628/*!
629@author Egtra
630@date   2007/10/22
631*/
632Function IntegerO_Convert(buf As *StrChar, xq As QWord, flags As FormatFlags) As DWord
633    Dim x = xq As DWord
634    Dim i = MaxSizeO
635    While x <> 0
636        buf[i] = ((x And &o7) + &h30) As StrChar
637        x >>= 3
638        i--
639    Wend
640    If flags And Alt Then
641        buf[i] = &h30
642        i--
643    End If
644    Return i
645End Function
646
647/*!
648@brief  IntegerO_ConvertのQWord版。
649@author Egtra
650@date   2007/10/26
651*/
652Function IntegerLO_Convert(buf As *StrChar, x As QWord, flags As FormatFlags) As DWord
653    Dim i = MaxSizeLO
654    While x <> 0
655        buf[i] = ((x And &o7) + &h30) As StrChar
656        x >>= 3
657        i--
658    Wend
659    If flags And Alt Then
660        buf[i] = &h30
661        i--
662    End If
663    Return i
664End Function
665
666/*!
667@author Egtra
668@date   2007/10/22
669@note   #フラグ (Alt)の処理は、IntegerO/LO_Convert内で行うので、ここで処理することはない。
670*/
671Function IntegerO_Prefix(x As QWord, flags As FormatFlags) As String
672    If flags And BPrefix Then
673        If x <> 0 Then
674            IntegerO_Prefix = "&O"
675        End If
676    End If
677End Function
678
679/*!
680@brief  DWordの最大値の十六進法表現ffffffffの文字数 - 1。FormatIntegerO内で使用。
681@author Egtra
682@date   2007/10/24
683*/
684Const MaxSizeX = 7
685
686/*!
687@brief  QWordの最大値の十六進法表現ffffffffffffffffの文字数 - 1。FormatIntegerO内で使用。
688@author Egtra
689@date   2007/10/26
690*/
691Const MaxSizeLX = 15
692
693/*!
694@author Egtra
695@date   2007/10/24
696*/
697Dim TraitsIntegerX[1] As IntegerConvertTraits
698With TraitsIntegerX[0]
699    .Convert = AddressOf(IntegerX_Convert)
700    .Prefix = AddressOf(IntegerX_Prefix)
701    .MaxSize = MaxSizeX
702End With
703
704With TraitsIntegerX[1]
705    .Convert = AddressOf(IntegerLX_Convert)
706    .Prefix = AddressOf(IntegerX_Prefix)
707    .MaxSize = MaxSizeLX
708End With
709
710/*!
711@brief  整数をprintfの%x, %X(十六進法)相当の変換で文字列化する関数。
712@author Egtra
713@date   2007/10/19
714@param[in]  x   文字列化する整数値。
715@param[in]  d   精度、最小限表示される桁数。DWORD_MAXのとき、指定なしとして、既定値1となる。
716@param[in]  field   フィールド幅。
717@param[in]  flags   書式フラグ。
718@return xの文字列表現
719*/
720Function FormatIntegerX(x As DWord, d As DWord, field As DWord, flags As FormatFlags) As String
721    Return FormatIntegerEx(TraitsIntegerX[0], x, d, field, flags)
722End Function
723
724/*!
725@brief  FormatIntegerXのQWord版。
726@author Egtra
727@date   2007/10/22
728*/
729Function FormatIntegerLX(x As QWord, d As DWord, field As DWord, flags As FormatFlags) As String
730    Return FormatIntegerEx(TraitsIntegerX[1], x, d, field, flags)
731End Function
732
733/*!
734@author Egtra
735@date   2007/10/22
736*/
737Function IntegerX_Convert(buf As *StrChar, xq As QWord, flags As FormatFlags) As DWord
738    Dim i = MaxSizeX
739    Dim x = xq As DWord
740    While x <> 0
741        buf[i] = _System_HexadecimalTable[x And &h0f]
742        x >>= 4
743        i--
744    Wend
745    Return i
746End Function
747
748/*!
749@brief  IntegerX_ConvertのQWord版。
750@author Egtra
751@date   2007/10/22
752*/
753Function IntegerLX_Convert(buf As *StrChar, x As QWord, flags As FormatFlags) As DWord
754    Dim i = MaxSizeLX
755    While x <> 0
756        buf[i] = _System_HexadecimalTable[x And &h0f]
757        x >>= 4
758        i--
759    Wend
760    Return i
761End Function
762
763/*!
764@author Egtra
765@date   2007/10/24
766*/
767Function IntegerX_Prefix(x As QWord, flags As FormatFlags) As String
768    If x <> 0 Then
769        If flags And Alt Then
770            IntegerX_Prefix = "0X"
771        ElseIf flags And BPrefix Then
772            IntegerX_Prefix = "&H"
773        End If
774    End If
775End Function
776
777/*!
778@brief  FormatIntegerExへ渡す変換特性を表す構造体型。
779@author Egtra
780@date   2007/10/22
781
782FormatIntegerの都合上、このファイル内で宣言しているIntegerConvertTraits型の
783変数は全て配列となっている;[0]が32ビット変換、[1]が64ビット変換である。
784*/
785Type IntegerConvertTraits
786    '!変換を行う関数へのポインタ。
787    Convert As *Function(buf As *StrChar, x As QWord, flags As FormatFlags) As DWord
788    '!接頭辞を取得する関数へのポインタ。
789    Prefix As *Function(x As QWord, flags As FormatFlags) As String
790    '!必要なバッファの大きさ。
791    MaxSize As DWord
792End Type
793
794/*!
795@brief  整数変換全てを行う関数。これを雛形とし、形式毎の差異はIntegerConvertTraitsで表現する。
796@author Egtra
797@date 2007/10/22
798@param[in] tr   特性情報。
799@param[in] x    変換元の数値。
800@param[in] d    精度。ここでは最低限出力する桁数。
801@param[in] field    フィールド幅。
802@param[in] flags    フラグ。
803*/
804Function FormatIntegerEx(ByRef tr As IntegerConvertTraits, x As QWord, d As DWord, field As DWord, flags As FormatFlags) As String
805    If d = DWORD_MAX Then
806        d = 1
807    Else
808        '精度が指定されているとき、ゼロフラグは無視される。
809        '仕様上、左揃えのときも無視されるが、それはAdjustFieldWidthが行ってくれる。
810        flags And= Not Zero
811    End If
812
813    Dim sb = New System.Text.StringBuilder
814    With sb
815        Dim prefixFunc = tr.Prefix
816        Dim prefix = prefixFunc(x, flags)
817        sb.Append(prefix)
818
819        Dim prefixLen = 0 As DWord
820        If String.IsNullOrEmpty(prefix) = False Then
821            prefixLen = prefix.Length As DWord
822        End If
823
824        Dim buf = GC_malloc_atomic((tr.MaxSize + 1) * SizeOf (StrChar)) As *StrChar
825        Dim convertFunc = tr.Convert
826        Dim bufStartPos = convertFunc(buf, x, flags)
827
828        Dim len = (tr.MaxSize - bufStartPos) As Long
829        If len < 0 Then
830            Debug
831        End If
832        If len < d Then
833            .Append(&h30 As StrChar, d - len)
834        End If
835
836        .Append(buf, bufStartPos + 1, len)
837
838        AdjustFieldWidth(sb, field, flags And (Not (Sign Or Blank)), prefixLen)
839    End With
840    FormatIntegerEx = sb.ToString()
841   
842    If (flags And Cap) = 0 Then
843        FormatIntegerEx = FormatIntegerEx.ToLower()
844    End If
845End Function
846
847/*!
848@brief  QWordの最大値18446744073709551615の文字数 - 1。FormatIntegerLU内で使用。
849@author Egtra
850@date   2007/09/18
851*/
852Const MaxSizeLU = 19
853
854/*!
855@brief  文字列をフィールド幅まで満たされるように空白などを挿入する。
856@author Egtra
857@date   2007/10/13
858@param[in,out] sb   対象文字列
859@param[in] field    フィールド幅
860@param[in] hasSign  符号を持っている(負の値か)か否か
861@param[in] flags    フラグ
862@param[in] prefixLen    (あれば)接頭辞の文字数。ゼロ埋めする際、この数だけ挿入位置を後ろにする。
863sbが"-1"のように負符号を持っている場合は、呼出元でSignフラグ(またはBlank)を立てること。
864*/
865Sub AdjustFieldWidth(sb As System.Text.StringBuilder, field As DWord, flags As FormatFlags, prefixLen = 0 As DWord)
866    With sb
867        If .Length < field Then
868            Dim embeddedSize = field - .Length
869            If flags And Left Then
870                .Append(&h20, embeddedSize)
871            Else
872                Dim insPos As Long
873                If (flags And Zero) <> 0 Then
874                    If (flags And Blank) Or (flags And Sign) Then
875                        insPos++
876                    End If
877                    insPos += prefixLen
878                    .Insert(insPos, String$(embeddedSize, "0"))
879                Else
880                    .Insert(insPos, String$(embeddedSize, " "))
881                End If
882            End If
883        End If
884    End With
885End Sub
886
887/*!
888@brief  文字列をprintfの%s相当の変換で書式化する関数。
889@author Egtra
890@date   2007/10/27
891@param[in]  x   文字列。
892@param[in]  d   精度、最大の文字数。
893@param[in]  field   フィールド幅。
894@param[in]  flags   書式フラグ。
895@return 書式化された文字列。
896*/
897Function FormatString(x As String, d As DWord, field As DWord, flags As FormatFlags) As String
898    Dim sb = New System.Text.StringBuilder(
899        x, 0, System.Math.Min(x.Length As DWord, d) As Long, field)
900    AdjustFieldWidth(sb, field, flags And Left)
901    FormatString = sb.ToString()
902End Function
903
904/*!
905@brief  文字をprintfの%c相当の変換で書式化する関数。
906@author Egtra
907@date   2007/10/27
908@param[in]  x   文字。
909@param[in]  d   精度、最大の文字数。
910@param[in]  field   フィールド幅。
911@param[in]  flags   書式フラグ。
912@return 書式化された文字列。
913*/
914Function FormatCharacter(x As StrChar, d As DWord, field As DWord, flags As FormatFlags) As String
915    Dim sb = New System.Text.StringBuilder(field + 1)
916    sb.Append(x)
917    AdjustFieldWidth(sb, field, flags And Left)
918    FormatCharacter = sb.ToString()
919End Function
920
921/*!
922@author Egtra
923@date   2007/10/28
924*/
925TypeDef FormatFloatProc = *Function(x As Double, precision As DWord, fieldWidth As DWord, flags As FormatFlags) As String
926
927/*!
928@author Egtra
929@date   2007/10/28
930*/
931Sub FormatFloat(s As System.Text.StringBuilder, formatProc As FormatFloatProc,
932    param As Object, precision As DWord, field As DWord, flags As FormatFlags)
933
934    Dim x As Double
935    Dim typeName = param.GetType().FullName
936    If typeName = "System.Double" Then
937        x = param As System.Double
938    ElseIf typeName = "System.Single" Then
939        x = param As System.Single
940    End If
941    s.Append(formatProc(x, precision, field, flags))
942End Sub
943
944/*!
945@author Egtra
946@date   2007/10/28
947*/
948Sub FormatInteger(s As System.Text.StringBuilder, traits As *IntegerConvertTraits,
949    param As Object, signed As Boolean, typeWidth As Long, precision As DWord, field As DWord, flags As FormatFlags)
950
951    Dim x As QWord
952    Dim typeName = param.GetType().FullName
953    If typeName = "System.UInt64" Then
954        x = param As System.UInt64
955    ElseIf typeName = "System.Int64" Then
956        x = (param As System.Int64) As QWord
957    ElseIf typeName = "System.UInt32" Then
958        x = param As System.UInt32
959    ElseIf typeName = "System.Int32" Then
960        x = (param As System.Int32) As QWord
961    ElseIf typeName = "System.UInt16" Then
962        x = param As System.UInt16
963    ElseIf typeName = "System.Int16" Then
964        x = (param As System.Int16) As QWord
965    ElseIf typeName = "System.UInt8" Then
966        x = param As System.Byte
967    ElseIf typeName = "System.Int8" Then
968        x = (param As System.SByte) As QWord
969    End If
970    '一旦縮めた後、符号・ゼロ拡張させる。
971    'また、64ビット整数なら64ビット変換Traitsを選択する。
972    If signed Then
973        If typeWidth = 1 Then
974            traits = VarPtr(traits[1])
975        ElseIf typeWidth = 0 Then
976            x = (((x As DWord) As Long) As Int64) As QWord
977        ElseIf typeWidth = -1 Then
978            x = (((x As Word) As Integer) As Int64) As QWord
979        ElseIf typeWidth = -2 Then
980            x = (((x As Byte) As SByte) As Int64) As QWord
981        End If
982    Else
983        If typeWidth = 1 Then
984            traits = VarPtr(traits[1])
985        ElseIf typeWidth = 0 Then
986            x = x As DWord
987        ElseIf typeWidth = -1 Then
988            x = x As Word
989        ElseIf typeWidth = -2 Then
990            x = x As Byte
991        End If
992    End If
993
994    s.Append(FormatIntegerEx(ByVal traits, x, precision, field, flags))
995End Sub
996
997'Format関数群ここまで
998'----
999
1000/*!
1001@brief  文字列から数値への変換。さらに変換に使われなかった文字列の位置を返す。
1002@author Egtra
1003@date   2007/11/11
1004@param[in] s    変換する文字
1005@param[out] p   変換に使われなかった部分の先頭を指すポインタ
1006@return 変換して得られた数値。変換できなければ0。
1007*/
1008Function StrToLong(s As *StrChar, ByRef p As *StrChar) As Long
1009    Dim negative As Boolean
1010    Dim i = 0 As Long
1011    If s[i] = &h2d Then 'Asc("-")
1012        i++
1013        negative = True
1014    End If
1015    Do
1016        Dim c = s[i]
1017        If Not IsDigit(c) Then Exit Do
1018        StrToLong *= 10
1019        StrToLong += ((c As DWord) And &h0f) As Long
1020        i++
1021    Loop
1022    If negative Then
1023        StrToLong = -StrToLong
1024    End If
1025    p = VarPtr(s[i])
1026End Function
1027
1028/*!
1029@brief  文字が十進数字かどうか調べる。
1030@author Egtra
1031@date   2007/11/11
1032@param[in] c    調べる文字
1033@retval True    0から9の文字である
1034@retval False   そうでない
1035*/
1036Function IsDigit(c As StrChar) As Boolean
1037    Dim dw = (c As DWord)
1038    IsDigit = (dw - &h30) < 10
1039End Function
1040
1041/*!
1042@brief  フィールド幅、精度用の数値読取
1043@author Egtra
1044@date   2007/11/11
1045@param[in, out] fmt 読み途中の書式指定
1046@param[in] params
1047@param[in, out] paramsCount
1048@param[out] ret 読み取った数値。読み取られなかったときの値は不定。
1049@retval True    読取を行った
1050@retval False   行わなかった
1051fmt[0]が*のときにはparamsから1つ読み取る。
1052そうでなく、fmtに数字(先頭に-符号があっても可)が並んでいれば、それを読み取る。
1053*/
1054Function ReadInt(ByRef fmt As *StrChar, params As *Object, ByRef paramsCount As SIZE_T, ByRef ret As Long) As Boolean
1055    If fmt[0] = &h2a Then '*
1056        fmt++ 'p
1057        ret = params[paramsCount] As System.Int32
1058        paramsCount++
1059        ReadInt = True
1060    Else
1061        Dim p As PSTR
1062        ret = StrToLong(fmt, p)
1063        If fmt <> p Then
1064            fmt = p
1065            ReadInt = True
1066        Else
1067            ReadInt = False
1068        End If
1069    End If
1070End Function
1071
1072/*!
1073@brief  フラグ指定の読み込み
1074@author Egtra
1075@date   2007/10/28
1076@param[in, out] fmt
1077@param[out] flags
1078@retval True    読み込みが完了した。
1079@retval False   読み取り中に文字列が終了した(ヌル文字が現れた)。
1080*/
1081Function ReadFlags(ByRef fmt As *StrChar, ByRef flags As FormatFlags) As Boolean
1082    ReadFlags = False
1083    Do
1084        Select Case fmt[0]
1085            Case &h23 '#
1086                flags Or= Alt
1087            Case &h30 '0
1088                flags Or= Zero
1089            Case &h20 '空白
1090                flags Or= Blank
1091            Case &h2b '+
1092                flags Or= Sign
1093            Case &h2d '-
1094                flags Or = Left
1095            Case &h26 '&
1096                flags Or= BPrefix
1097            Case 0
1098                Exit Function
1099            Case Else
1100                Exit Do
1101        End Select
1102        fmt++ 'p
1103    Loop
1104    ReadFlags = True
1105End Function
1106
1107/*!
1108@brief  フィールド幅指定の読み込み
1109@author Egtra
1110@date   2007/10/29
1111@param[in, out] fmt
1112@param[in] params
1113@param[in, out] paramsCount
1114@param[out] fieldWidth
1115@param[in, out] flags
1116*/
1117Sub ReadFieldWidth(ByRef fmt As *StrChar, params As *Object, ByRef paramsCount As SIZE_T,
1118    ByRef fieldWidth As DWord, ByRef flags As FormatFlags)
1119    Dim t As Long
1120    If ReadInt(fmt, params, paramsCount, t) Then
1121        If t < 0 Then
1122            flags Or= Left
1123            fieldWidth = -t As DWord
1124        Else
1125            fieldWidth = t As DWord
1126        End If
1127    Else
1128        fieldWidth = 0
1129    End If
1130End Sub
1131
1132/*!
1133@brief  精度の読み込み
1134@author Egtra
1135@date   2007/10/29
1136@param[in, out] fmt
1137@param[in] params
1138@param[in, out] paramsCount
1139@return 読み取った精度。指定がなかったときには、DWORD_MAX。
1140*/
1141Function ReadPrecision(ByRef fmt As *StrChar,
1142    params As *Object, ByRef paramsCount As SIZE_T) As DWord
1143
1144    If fmt[0] = &h2e Then '.
1145        fmt++
1146        Dim t As Long
1147        ReadPrecision = 0
1148        If ReadInt(fmt, params, paramsCount, t) Then
1149            If t > 0 Then
1150                ReadPrecision = t As DWord
1151            End If
1152        End If
1153    Else
1154        ReadPrecision = DWORD_MAX
1155    End If
1156End Function
1157
1158/*!
1159@biref  長さ指定の読み込み
1160@author Egtra
1161@date   2007/10/29
1162@param[in, out] fmt
1163@param[out] lengthSpec
1164*/
1165Sub ReadLength(ByRef fmt As *StrChar, ByRef lengthSpec As Long)
1166    Do
1167        Select Case fmt[0]
1168            Case &h6c 'l
1169                lengthSpec++
1170            Case &h68 'h
1171                lengthSpec--
1172            Case &h6a 'j (u)intmax_t
1173                lengthSpec = 1
1174#ifdef _WIN64
1175            Case &h74 't ptrdiff_t
1176                lengthSpec = 1
1177            Case &h7a 'z (s)size_t,
1178                lengthSpec = 1
1179#else
1180            Case &h74 't ptrdiff_t
1181                lengthSpec = 0
1182            Case &h7a 'z (s)size_t,
1183                lengthSpec = 0
1184#endif
1185            Case Else
1186                Exit Sub
1187        End Select
1188        fmt++ 'p
1189    Loop
1190End Sub
1191
1192/*!
1193@author Egtra
1194@date   2007/10/27
1195@todo   %nへの対応
1196*/
1197Function SPrintf(format As String, params As *Object, n As SIZE_T) As String
1198    Dim i = 0 As DWord
1199    Dim paramsCount = 0 As SIZE_T
1200    Dim fmt = StrPtr(format)
1201    Dim s = New System.Text.StringBuilder
1202    Do
1203        Dim last = format.Length - (fmt - StrPtr(format)) As Long 'p
1204        Dim pos = ActiveBasic.Strings.ChrFind(fmt, last, &h25 As StrChar) '&h25 = %
1205        If pos = -1 Then
1206            s.Append(fmt, 0, last)
1207            Exit Do
1208        End If
1209        '%以前の部分
1210        s.Append(fmt, 0, pos)
1211        fmt += pos + 1 'p
1212        'フラグの読取
1213        Dim flags = None As FormatFlags
1214        If ReadFlags(fmt, flags) = False Then
1215            Exit Do
1216        End If
1217        'フィールド幅
1218        Dim fieldWidth As DWord
1219        ReadFieldWidth(fmt, params, i, fieldWidth, flags)
1220        '精度
1221        Dim precision = ReadPrecision(fmt, params, i)
1222        '幅指定の読取
1223        Dim typeWidth As Long
1224        ReadLength(fmt, typeWidth)
1225
1226        Select Case fmt[0]
1227            Case &h64 'd
1228                FormatInteger(s, TraitsIntegerD, params[i], True, typeWidth, precision, fieldWidth, flags)
1229            Case &h69 'i
1230                FormatInteger(s, TraitsIntegerD, params[i], True, typeWidth, precision, fieldWidth, flags)
1231            Case &h75 'u
1232                FormatInteger(s, TraitsIntegerU, params[i], False, typeWidth, precision, fieldWidth, flags)
1233            Case &h6f 'o
1234                FormatInteger(s, TraitsIntegerO, params[i], False, typeWidth, precision, fieldWidth, flags)
1235            Case &h4f 'O
1236                FormatInteger(s, TraitsIntegerO, params[i], False, typeWidth, precision, fieldWidth, flags Or Cap)
1237            Case &h78 'x
1238                FormatInteger(s, TraitsIntegerX, params[i], False, typeWidth, precision, fieldWidth, flags)
1239            Case &h58 'X
1240                FormatInteger(s, TraitsIntegerX, params[i], False, typeWidth, precision, fieldWidth, flags Or Cap)
1241            Case &h65 'e
1242                FormatFloat(s, AddressOf(FormatFloatE), params[i], precision, fieldWidth, flags)
1243            Case &h45 'E
1244                FormatFloat(s, AddressOf(FormatFloatE), params[i], precision, fieldWidth, flags Or Cap)
1245            Case &h66 'f
1246                FormatFloat(s, AddressOf(FormatFloatF), params[i], precision, fieldWidth, flags)
1247            Case &h46 'F
1248                FormatFloat(s, AddressOf(FormatFloatF), params[i], precision, fieldWidth, flags Or Cap)
1249            Case &h67 'g
1250                FormatFloat(s, AddressOf(FormatFloatG), params[i], precision, fieldWidth, flags)
1251            Case &h47 'G
1252                FormatFloat(s, AddressOf(FormatFloatG), params[i], precision, fieldWidth, flags Or Cap)
1253            Case &h61 'a
1254                FormatFloat(s, AddressOf(FormatFloatA), params[i], precision, fieldWidth, flags)
1255            Case &h41 'A
1256                FormatFloat(s, AddressOf(FormatFloatA), params[i], precision, fieldWidth, flags Or Cap)
1257            Case &h73 's
1258                s.Append(FormatString(params[i] As String, precision, fieldWidth, flags))
1259            Case &h63 'c
1260                s.Append(FormatCharacter(params[i] As BoxedStrChar, precision, fieldWidth, flags))
1261'           Case &h6e 'n
1262            Case &h25 '%
1263                s.Append(&h25 As StrChar)
1264                i--
1265            Case 0
1266                Exit Do
1267        End Select
1268        fmt++ 'p
1269        i++
1270    Loop
1271    SPrintf = s.ToString
1272End Function
1273
1274End Namespace 'Detail
1275
1276/*!
1277@brief  Cのsprintfのような書式化関数10引数版
1278@author Egtra
1279@date   2007/10/27
1280@param[in] format   書式指定
1281@param[in] paramN   引数
1282@return 書式化された文字列
1283*/
1284
1285Function SPrintf(format As String, param0 As Object,
1286    param1 As Object, param2 As Object, param3 As Object,
1287    param4 As Object, param5 As Object, param6 As Object,
1288    param7 As Object, param8 As Object, param9 As Object) As String
1289#ifdef _WIN64
1290    'コンパイラがどういうコードを吐くのかわからないので、安全策を取る。
1291    Dim params[9] = [param0, param1, param2, param3, param4,
1292        param5, param6, param7, param8, param9] As Object
1293#else
1294    Dim params = VarPtr(param0) As *Object
1295#endif
1296    SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 10)
1297End Function
1298
1299/*!
1300@brief  Cのsprintfのような書式化関数9引数版
1301@author Egtra
1302@date   2007/10/27
1303@param[in] format   書式指定
1304@param[in] paramN   引数
1305@return 書式化された文字列
1306*/
1307Function SPrintf(format As String, param0 As Object,
1308    param1 As Object, param2 As Object, param3 As Object,
1309    param4 As Object, param5 As Object, param6 As Object,
1310    param7 As Object, param8 As Object) As String
1311#ifdef _WIN64
1312    Dim params[8] = [param0, param1, param2, param3, param4,
1313        param5, param6, param7, param8] As Object
1314#else
1315    Dim params = VarPtr(param0) As *Object
1316#endif
1317    SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 9)
1318End Function
1319
1320/*!
1321@brief  Cのsprintfのような書式化関数8引数版
1322@author Egtra
1323@date   2007/10/27
1324@param[in] format   書式指定
1325@param[in] paramN   引数
1326@return 書式化された文字列
1327*/
1328Function SPrintf(format As String, param0 As Object,
1329    param1 As Object, param2 As Object, param3 As Object,
1330    param4 As Object, param5 As Object, param6 As Object,
1331    param7 As Object) As String
1332#ifdef _WIN64
1333    Dim params[7] = [param0, param1, param2, param3, param4,
1334        param5, param6, param7] As Object
1335#else
1336    Dim params = VarPtr(param0) As *Object
1337#endif
1338    SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 8)
1339End Function
1340
1341/*!
1342@brief  Cのsprintfのような書式化関数7引数版
1343@author Egtra
1344@date   2007/10/27
1345@param[in] format   書式指定
1346@param[in] paramN   引数
1347@return 書式化された文字列
1348*/
1349Function SPrintf(format As String, param0 As Object,
1350    param1 As Object, param2 As Object, param3 As Object,
1351    param4 As Object, param5 As Object, param6 As Object) As String
1352#ifdef _WIN64
1353    Dim params[6] = [param0, param1, param2, param3, param4,
1354        param5, param6] As Object
1355#else
1356    Dim params = VarPtr(param0) As *Object
1357#endif
1358    SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 7)
1359End Function
1360
1361/*!
1362@brief  Cのsprintfのような書式化関数6引数版
1363@author Egtra
1364@date   2007/10/27
1365@param[in] format   書式指定
1366@param[in] paramN   引数
1367@return 書式化された文字列
1368*/
1369Function SPrintf(format As String, param0 As Object,
1370    param1 As Object, param2 As Object, param3 As Object,
1371    param4 As Object, param5 As Object) As String
1372#ifdef _WIN64
1373    Dim params[5] = [param0, param1, param2, param3, param4,
1374        param5] As Object
1375#else
1376    Dim params = VarPtr(param0) As *Object
1377#endif
1378    SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 6)
1379End Function
1380
1381/*!
1382@brief  Cのsprintfのような書式化関数5引数版
1383@author Egtra
1384@date   2007/10/27
1385@param[in] format   書式指定
1386@param[in] paramN   引数
1387@return 書式化された文字列
1388*/
1389Function SPrintf(format As String, param0 As Object,
1390    param1 As Object, param2 As Object, param3 As Object,
1391    param4 As Object) As String
1392#ifdef _WIN64
1393    Dim params[4] = [param0, param1, param2, param3, param4] As Object
1394#else
1395    Dim params = VarPtr(param0) As *Object
1396#endif
1397    SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 5)
1398End Function
1399
1400/*!
1401@brief  Cのsprintfのような書式化関数4引数版
1402@author Egtra
1403@date   2007/10/27
1404@param[in] format   書式指定
1405@param[in] paramN   引数
1406@return 書式化された文字列
1407*/
1408Function SPrintf(format As String, param0 As Object,
1409    param1 As Object, param2 As Object, param3 As Object) As String
1410#ifdef _WIN64
1411    Dim params[3] = [param0, param1, param2, param3] As Object
1412#else
1413    Dim params = VarPtr(param0) As *Object
1414#endif
1415    SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 4)
1416End Function
1417
1418/*!
1419@brief  Cのsprintfのような書式化関数3引数版
1420@author Egtra
1421@date   2007/10/27
1422@param[in] format   書式指定
1423@param[in] paramN   引数
1424@return 書式化された文字列
1425*/
1426Function SPrintf(format As String, param0 As Object,
1427    param1 As Object, param2 As Object) As String
1428#ifdef _WIN64
1429    Dim params[2] = [param0, param1, param2] As Object
1430#else
1431    Dim params = VarPtr(param0) As *Object
1432#endif
1433    SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 3)
1434End Function
1435
1436/*!
1437@brief  Cのsprintfのような書式化関数2引数版
1438@author Egtra
1439@date   2007/10/27
1440@param[in] format   書式指定
1441@param[in] paramN   引数
1442@return 書式化された文字列
1443*/
1444Function SPrintf(format As String, param0 As Object,
1445    param1 As Object) As String
1446#ifdef _WIN64
1447    Dim params[1] = [param0, param1] As Object
1448#else
1449    Dim params = VarPtr(param0) As *Object
1450#endif
1451    SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 2)
1452End Function
1453
1454/*!
1455@brief  Cのsprintfのような書式化関数1引数版
1456@author Egtra
1457@date   2007/10/27
1458@param[in] format   書式指定
1459@param[in] paramN   引数
1460@return 書式化された文字列
1461*/
1462Function SPrintf(format As String, param0 As Object) As String
1463    Dim params = VarPtr(param0) As *Object
1464    SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, params, 1)
1465End Function
1466
1467/*!
1468@brief  Cのsprintfのような書式化関数0引数版
1469@author Egtra
1470@date   2007/10/27
1471@param[in] format   書式指定
1472@param[in] paramN   引数
1473@return 書式化された文字列
1474*/
1475Function SPrintf(format As String) As String
1476    SPrintf = ActiveBasic.Strings.Detail.SPrintf(format, 0, 0)
1477End Function
1478
1479End Namespace 'Strings
1480End Namespace 'ActiveBasic
Note: See TracBrowser for help on using the repository browser.