Update pb-to-cpp.uc

Update pb-to-cpp.uc

Added StdOut

# pb-to-cpp.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.5 on 2/21/2014 1:26:21 PM
# Comment: Converts PB source code to C++; modified by Daniel Corbier

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: True
Exclude: False
Comment: Converts PB source code to C++; modified by Daniel Corbier
Selected: False
Highlight: False
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: True
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
Highlight: True
PassOnce: False
Find: {@Start}
Replace: // This file ({@Eval: Extract(ShortName(InputFile), ".")}.cpp) was converted from {@Eval: Extract(ShortName(InputFile), ".")}.Bas
         // with {@Eval: AppName} on {@Eval: TimeStamp()} using the Open Source
         // PowerBASIC to C++ converter found at https://github.com/uCalc/powerbasic-to-cpp

         {@Define:
            Var: Array As String
            Var: ArrayNames As Table
            Var: CleanUp As String
            Var: BitType As String
         }

Criteria: 2
Comment: Handles long line break (underscore _)
Pass: 1

Criteria: 3
Highlight: True
PassOnce: False
Find: {nl}{line} _ [{comment:".*"}] {nl}

Replace: {comment: ' {comment}{nl}}{nl}{line}{sp}

Criteria: 4
Highlight: True
SkipOver: True
Find: {"[\(\)]"} {@Note: These are ( and ); must be skipped}
Replace: [Skip over]

Criteria: 5
Highlight: True
SkipOver: True
Find: ' [{comment:".*"}]
Replace: [Skip over]

Criteria: 6
Comment: Functions, Subs, =
Pass: 2

Criteria: 7
Highlight: True
Find: =
Replace: ==

Criteria: 8
SkipOver: True
Find: !=
Replace: [Skip over]

Criteria: 9
Highlight: True
SkipOver: True
Find: { {nl}[%]|Then|Else|For|: } {var:" *[a-z\@\.\_]+"}[({index})] =
Replace: [Skip over]

Criteria: 10
Highlight: True
SkipOver: True
Find: { { #If | #ElseIf } Not | ' [{comment:".*"}] }
Replace: [Skip over]

Criteria: 11
Highlight: True
SkipOver: True
Find: Macro {name}[({params})] =
Replace: [Skip over]

Criteria: 12
Highlight: True
PassOnce: False
Find: Sub {name:1} [Alias {alias}]([{args}])[{exp: Export}] [{comment:" *'.*"}] {nl}
         {code+}
      End Sub
Replace: {exp:extern "C" __declspec(dllexport)} void {exp:__stdcall} {name}({args}) { {comment}
            {code}
         !!ReleaseDynamicArrays!!}

Criteria: 13
Highlight: True
BackColor: DarkKhaki
PassOnce: False
Find: Function {name:1} [Alias {alias}]([{args}])[{exp: Export}] As {type}[{comment:" *'.*"}]{nl}
         {code+}
      End Function
Replace: {exp:extern "C" __declspec(dllexport)} {type} {exp:__stdcall} {name}({args}) { {comment}
            {code}
         !!ReleaseDynamicArrays!!}

Criteria: 14
Highlight: True
PassOnce: False
Find: Function PBMain [()] [As Long]
Replace: Function main() As Long

Criteria: 15
Highlight: True
PassOnce: False
Find: Declare Function {name:1} [Lib {lib}] [Alias {alias}]
      [([{args}])] As {type}
Replace: {lib: extern __declspec(dllimport)} {type} {name}({args})

Criteria: 16
Highlight: True
Find: Declare Sub {name:1} [Lib {lib}] [Alias {alias}]
      [([{args}])]
Replace: {lib: extern __declspec(dllimport)} void {name}({args})

Criteria: 17
Highlight: True
Find: Static
Replace: static dim

Criteria: 18
Comment: Misc
Pass: 3

Criteria: 19
Highlight: True
SkipOver: True
Find: // [{comment:".*"}]
Replace: [Skip over]

Criteria: 20
Highlight: True
Find: ' [{comment:".*"}]
Replace: // {comment}

Criteria: 21
Highlight: True
BackColor: Green
PassOnce: False
Find: {nl}%{equate} = {value}
Replace: {nl}const int {equate} = {value};

Criteria: 22
Highlight: True
BackColor: Green
Find: %{equate:"[a-z]+"}
Replace: {equate}

Criteria: 23
Highlight: True
BackColor: SandyBrown
Find: {"&h"}
Replace: 0x

Criteria: 24
Highlight: True
BackColor: Green
PassOnce: False
Find: If {cond} Then {statement} [Else {else}]{nl}
Replace: if ({cond}) {{statement}{nl}}{else: else {{else}{nl}}}{nl}

Criteria: 25
Highlight: True
PassOnce: False
Find: If {cond} Then {nl}
         {code+}
      End If
Replace: if ({cond}) {
            {code}
         }

Criteria: 26
Highlight: True
PassOnce: False
Find: For {x} = {start} To {stop} [Step {inc=1}]{nl}
         {code+}
      Next
Replace: for ({x}={start}; {x}{@Eval: IIF(sgn({inc})>0, '<', '>')}={stop}; {x} += {inc}) {
            {code}
         }

Criteria: 27
Highlight: True
PassOnce: False
Find: While {cond} {nl}
         {code+}
      Wend
Replace: while ({cond}) {
            {code}
         }

Criteria: 28
Highlight: True
PassOnce: False
Find: Do { {while: While} | {until: Until} } {cond} {nl}
         {code+}
      Loop
Replace: while ({while: {cond}}{until:!({cond})}) {
            {code}
         }

Criteria: 29
Highlight: True
PassOnce: False
Find: Do{nl}
         {code+}
      Loop { {while: While} | {until: Until} } {cond}
Replace: do {
            {code}
         } while ({while: {cond}}{until:!({cond})})

Criteria: 30
Highlight: True
Find: !!ReleaseDynamicArrays!!
Replace: {@Eval:
            CleanUp = ""
            uc_For(x, Count(ArrayNames), 1, -1,
               Array = ReadKey(ArrayNames, x)
               CleanUp=CleanUp+"delete[] "+Array+";{nl}"
               Delete(ArrayNames, Array)
            )
            CleanUp
         }

Criteria: 31
Highlight: True
BackColor: Orange
PassOnce: False
Find: { Dim | {member: {nl}}} {var:1} As {type} [{ptr: Ptr}]
Replace: {member: {nl}}{type} {ptr:*}{var};

Criteria: 32
Highlight: True
PassOnce: False
Find: {nl} {bitfield:1} As Bit * {size} [{in: In {type}}]
Replace: {nl}{@Eval:
            IIf("{type}" <> "", SetVar(BitType, "{type}"))
            BitType
         } {bitfield} : {size};

Criteria: 33
Highlight: True
PassOnce: False
Find: Dim {array}({subscript}) As {type}
Replace: {type} *{array} = new {type} [{subscript}+1];{@Eval:
            Insert(ArrayNames, "{array}")
         }{@Define:: Syntax: {array}({index}) ::= {array}[{index}]}

Criteria: 34
Highlight: True
BackColor: SandyBrown
PassOnce: False
Find: Dim {var1}, {more}
Replace: Dim {var1}
         Dim {more}

Criteria: 35
Highlight: True
BackColor: Gold
PassOnce: False
Find: { Local | Global | Register }
Replace: Dim

Criteria: 36
Highlight: True
Find: @
Replace: *

Criteria: 37
Highlight: True
BackColor: Silver
Find: VarPtr({var})
Replace: &{var}

Criteria: 38
Highlight: True
BackColor: DeepSkyBlue
PassOnce: False
Find: Function = {value}
Replace: return {value}

Criteria: 39
Find: Iterate
Replace: continue

Criteria: 40
Find: Exit
Replace: break

Criteria: 41
Highlight: True
Find: Exit Sub
Replace: return

Criteria: 42
Highlight: True
BackColor: Lime
Find: Long
Replace: int

Criteria: 43
Highlight: True
BackColor: Red
Find: Single
Replace: float

Criteria: 44
Highlight: True
Find: { Double | Extended | Ext }
Replace: double{@Note: May instead use "long double" for Extended}

Criteria: 45
Highlight: True
Find: Byte
Replace: unsigned char

Criteria: 46
Highlight: True
Find: Integer
Replace: short

Criteria: 47
Highlight: True
Find: Word
Replace: unsigned short

Criteria: 48
Highlight: True
Find: Dword
Replace: unsigned int

Criteria: 49
Find: AsciiZ
Replace: LPCSTR

Criteria: 50
Highlight: True
Find: Quad
Replace: __int64

Criteria: 51
Highlight: True
BackColor: SlateBlue
PassOnce: False
Find: ByRef {arg} As {type:1}
Replace: {type}& {arg}

Criteria: 52
Highlight: True
BackColor: Pink
PassOnce: False
Find: ByVal {arg} As {type:1} [{ptr: Ptr}]
Replace: {type} {ptr:*}{arg}

Criteria: 53
Highlight: True
PassOnce: False
Find: Type {name:1}
         {members+}
      End Type
Replace: struct {name} {
            {members}
         }

Criteria: 54
Highlight: True
Find: Macro {name} [{params: ({paramlist})}] = {replacement}
Replace: #define {name}{params} {replacement}

Criteria: 55
Highlight: True
Find: #If
Replace: #if

Criteria: 56
Highlight: True
Find: #Else
Replace: #else

Criteria: 57
Highlight: True
Find: #ElseIf
Replace: #elif

Criteria: 58
Highlight: True
Find: #EndIf
Replace: #endif

Criteria: 59
Highlight: True
PassOnce: False
Find: [{NOT: Not }] %Def({const})
Replace: {NOT:!}defined {const}

Criteria: 60
Find: Choose[&]({index}, {choice})
Replace: IIf({index}, {choice}, 0)

Criteria: 61
Find: Choose$({index}, {choice})
Replace: IIf({index}, {choice}, "")

Criteria: 62
PassOnce: False
Find: Choose[{type: $ | & }]({index}, {choice1}, {more})
Replace: IIf({index}, {choice1}, Choose{type}({index}, {more}))

Criteria: 63
Selected: True
Find: StdOut {text} { {sameline: ;} | {NewLine: } }
Replace: cout << {text} {NewLine: << endl;}

Criteria: 64
Comment: Adds semi-colons to statements
Pass: 4

Criteria: 65
Highlight: True
SkipOver: True
Find: { "{" | "}" | ; | //[{".*"}] | #{".*"} } {nl} [{"[ \n]+"}]
Replace: [Skip over]

Criteria: 66
Comment: Skips over so that colons in bit fields are not affected
Highlight: True
SkipOver: True
Find: struct {name:1} "{" {members+} "}"
Replace: [Skip over]

Criteria: 67
SkipOver: True
Find: ({cond} ? {this} :
Replace: [Skip over]

Criteria: 68
Highlight: True
Find: :
Replace: ;

Criteria: 69
SkipOver: True
Find: ::
Replace: [Skip over]

Criteria: 70
Highlight: True
PassOnce: False
Find: {nl}
Replace: ;{nl}

Criteria: 71
PassOnce: False
Find: IIf[$]({cond}, {this}, {that})
Replace: ({cond} ? {this} : {that})

Criteria: 72
Find: _char([{char= }])
Replace: '{char}'

# End Search

# pb-to-cpp.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.5 on 2/20/2014 10:22:18 AM
# Comment: Converts PB source code to C++; modified by Daniel Corbier

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: True
Exclude: False
Comment: Converts PB source code to C++; modified by Daniel Corbier
Selected: False
Highlight: False
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: True
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
Highlight: True
PassOnce: False
Find: {@Start}
Replace: // This file ({@Eval: Extract(ShortName(InputFile), ".")}.cpp) was converted from {@Eval: Extract(ShortName(InputFile), ".")}.Bas
         // with {@Eval: AppName} on {@Eval: TimeStamp()} using the Open Source
         // PowerBASIC to C++ converter found at https://github.com/uCalc/powerbasic-to-cpp

         {@Define:
            Var: Array As String
            Var: ArrayNames As Table
            Var: CleanUp As String
            Var: BitType As String
         }

Criteria: 2
Comment: Handles long line break (underscore _)
Pass: 1

Criteria: 3
Highlight: True
PassOnce: False
Find: {nl}{line} _ [{comment:".*"}] {nl}

Replace: {comment: ' {comment}{nl}}{nl}{line}{sp}

Criteria: 4
Highlight: True
SkipOver: True
Find: {"[\(\)]"} {@Note: These are ( and ); must be skipped}
Replace: [Skip over]

Criteria: 5
Highlight: True
SkipOver: True
Find: ' [{comment:".*"}]
Replace: [Skip over]

Criteria: 6
Comment: Functions, Subs, =
Pass: 2

Criteria: 7
Highlight: True
Find: =
Replace: ==

Criteria: 8
SkipOver: True
Find: !=
Replace: [Skip over]

Criteria: 9
Highlight: True
SkipOver: True
Find: { {nl}[%]|Then|Else|For|: } {var:" *[a-z\@\.\_]+"}[({index})] =
Replace: [Skip over]

Criteria: 10
Highlight: True
SkipOver: True
Find: { { #If | #ElseIf } Not | ' [{comment:".*"}] }
Replace: [Skip over]

Criteria: 11
Highlight: True
SkipOver: True
Find: Macro {name}[({params})] =
Replace: [Skip over]

Criteria: 12
Highlight: True
PassOnce: False
Find: Sub {name:1} [Alias {alias}]([{args}])[{exp: Export}] [{comment:" *'.*"}] {nl}
         {code+}
      End Sub
Replace: {exp:extern "C" __declspec(dllexport)} void {exp:__stdcall} {name}({args}) { {comment}
            {code}
         !!ReleaseDynamicArrays!!}

Criteria: 13
Highlight: True
BackColor: DarkKhaki
PassOnce: False
Find: Function {name:1} [Alias {alias}]([{args}])[{exp: Export}] As {type}[{comment:" *'.*"}]{nl}
         {code+}
      End Function
Replace: {exp:extern "C" __declspec(dllexport)} {type} {exp:__stdcall} {name}({args}) { {comment}
            {code}
         !!ReleaseDynamicArrays!!}

Criteria: 14
Highlight: True
PassOnce: False
Find: Function PBMain [()] [As Long]
Replace: Function main() As Long

Criteria: 15
Highlight: True
PassOnce: False
Find: Declare Function {name:1} [Lib {lib}] [Alias {alias}]
      [([{args}])] As {type}
Replace: {lib: extern __declspec(dllimport)} {type} {name}({args})

Criteria: 16
Highlight: True
Find: Declare Sub {name:1} [Lib {lib}] [Alias {alias}]
      [([{args}])]
Replace: {lib: extern __declspec(dllimport)} void {name}({args})

Criteria: 17
Highlight: True
Find: Static
Replace: static dim

Criteria: 18
Comment: Misc
Pass: 3

Criteria: 19
Highlight: True
SkipOver: True
Find: // [{comment:".*"}]
Replace: [Skip over]

Criteria: 20
Highlight: True
Find: ' [{comment:".*"}]
Replace: // {comment}

Criteria: 21
Highlight: True
BackColor: Green
PassOnce: False
Find: {nl}%{equate} = {value}
Replace: {nl}const int {equate} = {value};

Criteria: 22
Highlight: True
BackColor: Green
Find: %{equate:"[a-z]+"}
Replace: {equate}

Criteria: 23
Highlight: True
BackColor: SandyBrown
Find: {"&h"}
Replace: 0x

Criteria: 24
Highlight: True
BackColor: Green
PassOnce: False
Find: If {cond} Then {statement} [Else {else}]{nl}
Replace: if ({cond}) {{statement}{nl}}{else: else {{else}{nl}}}{nl}

Criteria: 25
Highlight: True
PassOnce: False
Find: If {cond} Then {nl}
         {code+}
      End If
Replace: if ({cond}) {
            {code}
         }

Criteria: 26
Highlight: True
PassOnce: False
Find: For {x} = {start} To {stop} [Step {inc=1}]{nl}
         {code+}
      Next
Replace: for ({x}={start}; {x}{@Eval: IIF(sgn({inc})>0, '<', '>')}={stop}; {x} += {inc}) {
            {code}
         }

Criteria: 27
Highlight: True
PassOnce: False
Find: While {cond} {nl}
         {code+}
      Wend
Replace: while ({cond}) {
            {code}
         }

Criteria: 28
Highlight: True
PassOnce: False
Find: Do { {while: While} | {until: Until} } {cond} {nl}
         {code+}
      Loop
Replace: while ({while: {cond}}{until:!({cond})}) {
            {code}
         }

Criteria: 29
Highlight: True
PassOnce: False
Find: Do{nl}
         {code+}
      Loop { {while: While} | {until: Until} } {cond}
Replace: do {
            {code}
         } while ({while: {cond}}{until:!({cond})})

Criteria: 30
Highlight: True
Find: !!ReleaseDynamicArrays!!
Replace: {@Eval:
            CleanUp = ""
            uc_For(x, Count(ArrayNames), 1, -1,
               Array = ReadKey(ArrayNames, x)
               CleanUp=CleanUp+"delete[] "+Array+";{nl}"
               Delete(ArrayNames, Array)
            )
            CleanUp
         }

Criteria: 31
Highlight: True
BackColor: Orange
PassOnce: False
Find: { Dim | {member: {nl}}} {var:1} As {type} [{ptr: Ptr}]
Replace: {member: {nl}}{type} {ptr:*}{var};

Criteria: 32
Highlight: True
PassOnce: False
Find: {nl} {bitfield:1} As Bit * {size} [{in: In {type}}]
Replace: {nl}{@Eval:
            IIf("{type}" <> "", SetVar(BitType, "{type}"))
            BitType
         } {bitfield} : {size};

Criteria: 33
Highlight: True
PassOnce: False
Find: Dim {array}({subscript}) As {type}
Replace: {type} *{array} = new {type} [{subscript}+1];{@Eval:
            Insert(ArrayNames, "{array}")
         }{@Define:: Syntax: {array}({index}) ::= {array}[{index}]}

Criteria: 34
Highlight: True
BackColor: SandyBrown
PassOnce: False
Find: Dim {var1}, {more}
Replace: Dim {var1}
         Dim {more}

Criteria: 35
Highlight: True
BackColor: Gold
PassOnce: False
Find: { Local | Global | Register }
Replace: Dim

Criteria: 36
Highlight: True
Find: @
Replace: *

Criteria: 37
Highlight: True
BackColor: Silver
Find: VarPtr({var})
Replace: &{var}

Criteria: 38
Highlight: True
BackColor: DeepSkyBlue
PassOnce: False
Find: Function = {value}
Replace: return {value}

Criteria: 39
Find: Iterate
Replace: continue

Criteria: 40
Find: Exit
Replace: break

Criteria: 41
Highlight: True
Find: Exit Sub
Replace: return

Criteria: 42
Highlight: True
BackColor: Lime
Find: Long
Replace: int

Criteria: 43
Highlight: True
BackColor: Red
Find: Single
Replace: float

Criteria: 44
Highlight: True
Find: { Double | Extended | Ext }
Replace: double{@Note: May instead use "long double" for Extended}

Criteria: 45
Highlight: True
Find: Byte
Replace: unsigned char

Criteria: 46
Highlight: True
Find: Integer
Replace: short

Criteria: 47
Highlight: True
Find: Word
Replace: unsigned short

Criteria: 48
Highlight: True
Find: Dword
Replace: unsigned int

Criteria: 49
Find: AsciiZ
Replace: LPCSTR

Criteria: 50
Highlight: True
Find: Quad
Replace: __int64

Criteria: 51
Highlight: True
BackColor: SlateBlue
PassOnce: False
Find: ByRef {arg} As {type:1}
Replace: {type}& {arg}

Criteria: 52
Highlight: True
BackColor: Pink
PassOnce: False
Find: ByVal {arg} As {type:1} [{ptr: Ptr}]
Replace: {type} {ptr:*}{arg}

Criteria: 53
Highlight: True
PassOnce: False
Find: Type {name:1}
         {members+}
      End Type
Replace: struct {name} {
            {members}
         }

Criteria: 54
Highlight: True
Find: Macro {name} [{params: ({paramlist})}] = {replacement}
Replace: #define {name}{params} {replacement}

Criteria: 55
Highlight: True
Find: #If
Replace: #if

Criteria: 56
Highlight: True
Find: #Else
Replace: #else

Criteria: 57
Highlight: True
Find: #ElseIf
Replace: #elif

Criteria: 58
Highlight: True
Find: #EndIf
Replace: #endif

Criteria: 59
Highlight: True
PassOnce: False
Find: [{NOT: Not }] %Def({const})
Replace: {NOT:!}defined {const}

Criteria: 60
Find: Choose[&]({index}, {choice})
Replace: IIf({index}, {choice}, 0)

Criteria: 61
Find: Choose$({index}, {choice})
Replace: IIf({index}, {choice}, "")

Criteria: 62
PassOnce: False
Find: Choose[{type: $ | & }]({index}, {choice1}, {more})
Replace: IIf({index}, {choice1}, Choose{type}({index}, {more}))

Criteria: 63
Comment: Adds semi-colons to statements
Pass: 4

Criteria: 64
Highlight: True
SkipOver: True
Find: { "{" | "}" | ; | //[{".*"}] | #{".*"} } {nl} [{"[ \n]+"}]
Replace: [Skip over]

Criteria: 65
Comment: Skips over so that colons in bit fields are not affected
Highlight: True
SkipOver: True
Find: struct {name:1} "{" {members+} "}"
Replace: [Skip over]

Criteria: 66
Selected: True
SkipOver: True
Find: ({cond} ? {this} :
Replace: [Skip over]

Criteria: 67
Highlight: True
Find: :
Replace: ;

Criteria: 68
SkipOver: True
Find: ::
Replace: [Skip over]

Criteria: 69
Highlight: True
PassOnce: False
Find: {nl}
Replace: ;{nl}

Criteria: 70
PassOnce: False
Find: IIf[$]({cond}, {this}, {that})
Replace: ({cond} ? {this} : {that})

Criteria: 71
Find: _char([{char= }])
Replace: '{char}'

# End Search


Update beautify.uc

Update beautify.uc

Modified code to better handle embedded comments

# beautify.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.95 on 3/20/2014 6:31:38 PM
# Comment: Fixes indentation and spacing in C++ source code

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, InputFile, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique, FilterTally

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: True
Exclude: False
Comment: Fixes indentation and spacing in C++ source code
Selected: False
Highlight: False
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: True
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
FilterTally: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
InputFile:
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
Find:
Replace: {@Define:
            Var: Indentation   = 0
            Const: IndentSize  = 3
            SyntaxArg: {spc}   = [{"[ \n]+"}]
            Inline: {indent+} := Indentation += IndentSize
            Inline: {indent-} := Indentation -= IndentSize
            Inline: {indent}  := " " * Indentation
         }{@Eval: Indentation = 0}

Criteria: 2
Comment: Strips all indentation and some spacing
Pass: 1

Criteria: 3
BackColor: Brown
Find: {"\n"}{" +"}
Replace: {nl}

Criteria: 4
SkipOver: True
Find: ({code~})
Replace: [Skip over]

Criteria: 5
Comment:
Pass: 2

Criteria: 6
BackColor: RoyalBlue
Find: {spc} "{" {spc}
Replace: {

Criteria: 7
BackColor: Pink
Find: {spc} "}"
Replace: }

Criteria: 8
BackColor: Purple
Find: {" *; *"}
Replace: ;

Criteria: 9
Find: {" *, *"}
Replace: ,{sp}

Criteria: 10
Comment: Handles semicolons
Pass: 3

Criteria: 11
BackColor: Green
Find: ({params~})
Replace: ({@Eval: Replace({Q}{params}{Q}, ";", "; ")})

Criteria: 12
BackColor: SandyBrown
Find: ;{char:"[^\n]"}
Replace: ;{nl}{char}

Criteria: 13
Comment: Performs indentation
Pass: 4

Criteria: 14
BackColor: DeepSkyBlue
Find: {nl}
Replace: {nl}{indent}

Criteria: 15
BackColor: DarkKhaki
Find: "{" [{comment: //{c:".*"}}]
Replace: {sp}{{comment: {comment}}{nl}{indent+}{indent}

Criteria: 16
BackColor: Yellow
Find: "}" [{comment: //{c:".*"}}]
Replace: {nl}{indent-}{indent}}{comment: {comment}}

Criteria: 17
BackColor: Brown
Find: {nl}{type:1}{func:1}([{args+}])"{"
Replace: {nl}{type} {func}({args}){nl}{{indent+}{nl}{indent}

Criteria: 18
Find:
Replace:

# End Search

# beautify.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.5 on 1/14/2014 6:37:14 PM
# Comment: Fixes indentation and spacing in C++ source code

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: True
Exclude: False
Comment: Fixes indentation and spacing in C++ source code
Selected: False
Highlight: False
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: True
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
Find:
Replace: {@Define:
            Var: Indentation   = 0
            Const: IndentSize  = 3
            SyntaxArg: {spc}   = [{"[ \n]+"}]
            Inline: {indent+} := Indentation += IndentSize
            Inline: {indent-} := Indentation -= IndentSize
            Inline: {indent}  := " " * Indentation
         }{@Eval: Indentation = 0}

Criteria: 2
Comment: Strips all indentation and some spacing
Pass: 1

Criteria: 3
BackColor: Brown
Find: {"\n"}{" +"}
Replace: {nl}

Criteria: 4
BackColor: RoyalBlue
Find: {spc} "{" {spc}
Replace: {

Criteria: 5
BackColor: Pink
Find: {spc} "}"
Replace: }

Criteria: 6
BackColor: Purple
Find: {" *; *"}
Replace: ;

Criteria: 7
Find: {" *, *"}
Replace: ,{sp}

Criteria: 8
Comment: Handles semicolons
Pass: 2

Criteria: 9
Selected: True
BackColor: Green
Find: ({params~})
Replace: ({@Eval: Replace({Q}{params}{Q}, ";", "; ")})

Criteria: 10
BackColor: SandyBrown
Find: ;{char:"[^\n]"}
Replace: ;{nl}{char}

Criteria: 11
Comment: Performs indentation
Pass: 3

Criteria: 12
BackColor: DeepSkyBlue
Find: {nl}
Replace: {nl}{indent}

Criteria: 13
BackColor: DarkKhaki
Find: "{" [{comment: //{".*"}}]
Replace: {sp}{{comment: {comment}}{nl}{indent+}{indent}

Criteria: 14
BackColor: Yellow
Find: "}" [{comment: //{".*"}}]
Replace: {nl}{indent-}{indent}}{comment: {comment}}

Criteria: 15
BackColor: Brown
Find: {nl}{type:1}{func:1}([{args}])"{"
Replace: {nl}{type} {func}({args}){nl}{{indent+}{nl}{indent}

# End Search


Update pb-to-cpp.uc

Update pb-to-cpp.uc

Double quotes were replaced with single quotes in the Bitwise Replace statement to avoid interfering with double quotes that may be present in an expression.

# pb-to-cpp.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.0 on 12/27/2013 3:49:26 PM
# Comment: Converts PB source code to C++; modified by Daniel Corbier

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: True
Exclude: False
Comment: Converts PB source code to C++; modified by Daniel Corbier
Selected: False
Highlight: True
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: True
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
Find:
Replace: {@Define:
            Var: Array As String
            Var: ArrayNames As Table
            Var: CleanUp As String
            Var: BitType As String
         }

Criteria: 2
Comment: Handles long line break (underscore _)
Pass: 1

Criteria: 3
PassOnce: False
Find: {nl}{line} _ [{comment:".*"}] {nl}

Replace: {comment: ' {comment}{nl}}{nl}{line}{sp}

Criteria: 4
SkipOver: True
Find: {"[\(\)]"} {@Note: These are ( and ); must be skipped}
Replace: [Skip over]

Criteria: 5
SkipOver: True
Find: ' {comment:".*"}
Replace: [Skip over]

Criteria: 6
Comment: Processes some operators
Pass: 2

Criteria: 7
Comment: Bitwise AND and OR
Selected: True
Find: ({expr%})
Replace: ({@Eval: Replace(Replace(Replace('{expr}', "And", "&"), "Or", "|"), "=", "==")})

Criteria: 8
Comment: Logical (short-circuit) AND
Find: And
Replace: &&

Criteria: 9
Comment: Logical (short-circuit) OR
Find: Or
Replace: ||

Criteria: 10
Find: Xor
Replace: ^

Criteria: 11
Find: Not
Replace: ~

Criteria: 12
Find: IsFalse
Replace: !

Criteria: 13
Find: <>
Replace: !=

Criteria: 14
Find: =
Replace: ==

Criteria: 15
SkipOver: True
Find: { {nl}[%]|Then|Else|For|: } {var:" *[a-z\@\.]+"}[({index})] =
Replace: [Skip over]

Criteria: 16
SkipOver: True
Find: { { #If | #ElseIf } Not | ' {comment:".*"} }
Replace: [Skip over]

Criteria: 17
Comment:
Pass: 3

Criteria: 18
SkipOver: True
Find: // {comment~}
Replace: [Skip over]

Criteria: 19
Find: ' {comment~}
Replace: // {comment}

Criteria: 20
BackColor: Green
PassOnce: False
Find: {nl}%{equate} = {value}
Replace: {nl}const int {equate} = {value};

Criteria: 21
BackColor: Green
Find: %{equate}
Replace: {equate}

Criteria: 22
BackColor: SandyBrown
Find: {"&h"}
Replace: 0x

Criteria: 23
BackColor: Green
PassOnce: False
Find: If {cond} Then {statement} [Else {else}]{nl}
Replace: if ({cond}) { {statement} }{else: else {{else}}}{nl}

Criteria: 24
PassOnce: False
Find: If {cond} Then {nl}
         {code+}
      End If
Replace: if ({cond}) {
            {code}
         }

Criteria: 25
BackColor: DarkKhaki
PassOnce: False
Find: Function {name} ([{args}]) As {type}{nl}
         {code+}
      End Function
Replace: {type} {name}({args}) {
            {code}
         !!ReleaseDynamicArrays!!}

Criteria: 26
PassOnce: False
Find: Sub {name} ([{args}]){nl}
         {code+}
      End Sub
Replace: void {name}({args}) {
            {code}
         !!ReleaseDynamicArrays!!}

Criteria: 27
PassOnce: False
Find: For {x} = {start} To {stop} [Step {inc=1}]{nl}
         {code+}
      Next
Replace: for ({x}={start}; {x}{@Eval: IIF(sgn({inc})>0, '<', '>')}={stop}; {x} += {inc}) {
            {code}
         }

Criteria: 28
PassOnce: False
Find: While {cond} {nl}
         {code+}
      Wend
Replace: while ({cond}) {
            {code}
         }

Criteria: 29
Find: !!ReleaseDynamicArrays!!
Replace: {@Eval:
            CleanUp = ""
            uc_For(x, 1, Count(ArrayNames), 1,
               Array = ReadKey(ArrayNames, x)
               CleanUp=CleanUp+"delete[] "+Array+";{nl}"
               Delete(ArrayNames, Array)
            )
            CleanUp
         }

Criteria: 30
BackColor: Orange
PassOnce: False
Find: { Dim | {member: {nl}}} {var:1} As {type} [{ptr: Ptr}]
Replace: {member: {nl}}{type} {ptr:*}{var};

Criteria: 31
PassOnce: False
Find: {nl} {bitfield:1} As Bit * {size} [{in: In {type}}]
Replace: {nl}{@Eval:
            IIf("{type}" <> "", SetVar(BitType, "{type}"))
            BitType
         } {bitfield} : {size};

Criteria: 32
PassOnce: False
Find: Dim {array}({subscript}) As {type}
Replace: {type} *{array} = new {type} [{subscript}+1];{@Eval:
            Insert(ArrayNames, "{array}")
         }{@Define:: Syntax: {array}({index}) ::= {array}[{index}]}

Criteria: 33
BackColor: SandyBrown
PassOnce: False
Find: Dim {var1}, {more}
Replace: Dim {var1}
         Dim {more}

Criteria: 34
BackColor: Gold
PassOnce: False
Find: { Local | Global | Register }
Replace: Dim

Criteria: 35
Find: @
Replace: *

Criteria: 36
BackColor: Silver
Find: VarPtr({var})
Replace: &{var}

Criteria: 37
BackColor: DeepSkyBlue
PassOnce: False
Find: Function = {value}
Replace: return {value};

Criteria: 38
BackColor: Lime
Find: Long
Replace: long

Criteria: 39
BackColor: Red
Find: Single
Replace: float

Criteria: 40
Find: Double
Replace: double

Criteria: 41
Find: Byte
Replace: unsigned char

Criteria: 42
Find: Integer
Replace: short

Criteria: 43
Find: Word
Replace: unsigned short

Criteria: 44
Find: Dword
Replace: unsigned long

Criteria: 45
BackColor: SlateBlue
PassOnce: False
Find: ByRef {arg} As {type:1}
Replace: {type}& {arg}

Criteria: 46
BackColor: Pink
PassOnce: False
Find: ByVal {arg} As {type:1} [{ptr: Ptr}]
Replace: {type} {ptr:*}{arg}

Criteria: 47
PassOnce: False
Find: Type {name:1}
         {members+}
      End Type
Replace: struct {name} {
            {members}
         }

Criteria: 48
Find: #If
Replace: #if

Criteria: 49
Find: #Else
Replace: #else

Criteria: 50
Find: #ElseIf
Replace: #elif

Criteria: 51
Find: #EndIf
Replace: #endif

Criteria: 52
PassOnce: False
Find: [{NOT: Not }] %Def({const})
Replace: {NOT:!}defined {const}

Criteria: 53
Comment: Adds semi-colons to statements
Pass: 4

Criteria: 54
SkipOver: True
Find: { "{" | "}" | ; | //{".*"} | #{".*"} } {nl} [{"[ \n]+"}]
Replace: [Skip over]

Criteria: 55
Comment: Skips over so that colons in bit fields are not affected
SkipOver: True
Find: struct {name:1} "{" {members+} "}"
Replace: [Skip over]

Criteria: 56
Find: :
Replace: ;

Criteria: 57
PassOnce: False
Find: {nl}
Replace: ;{nl}

# End Search

# pb-to-cpp.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.0 on 12/26/2013 4:49:10 PM
# Comment: Converts PB source code to C++; modified by Daniel Corbier

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: True
Exclude: False
Comment: Converts PB source code to C++; modified by Daniel Corbier
Selected: False
Highlight: True
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: True
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
Find:
Replace: {@Define:
            Var: Array As String
            Var: ArrayNames As Table
            Var: CleanUp As String
            Var: BitType As String
         }

Criteria: 2
Comment: Handles long line break (underscore _)
Pass: 1

Criteria: 3
PassOnce: False
Find: {nl}{line} _ [{comment:".*"}] {nl}

Replace: {comment: ' {comment}{nl}}{nl}{line}{sp}

Criteria: 4
SkipOver: True
Find: {"[\(\)]"} {@Note: These are ( and ); must be skipped}
Replace: [Skip over]

Criteria: 5
SkipOver: True
Find: ' {comment:".*"}
Replace: [Skip over]

Criteria: 6
Comment: Processes some operators
Pass: 2

Criteria: 7
Comment: Bitwise AND and OR
Find: ({expr%})
Replace: ({@Eval: Replace(Replace(Replace("{expr}", "And", "&"), "Or", "|"), "=", "==")})

Criteria: 8
Comment: Logical (short-circuit) AND
Find: And
Replace: &&

Criteria: 9
Comment: Logical (short-circuit) OR
Find: Or
Replace: ||

Criteria: 10
Find: Xor
Replace: ^

Criteria: 11
Find: Not
Replace: ~

Criteria: 12
Find: IsFalse
Replace: !

Criteria: 13
Find: <>
Replace: !=

Criteria: 14
Find: =
Replace: ==

Criteria: 15
SkipOver: True
Find: { {nl}[%]|Then|Else|For|: } {var:" *[a-z\@\.]+"}[({index})] =
Replace: [Skip over]

Criteria: 16
Selected: True
SkipOver: True
Find: { { #If | #ElseIf } Not | ' {comment:".*"} }
Replace: [Skip over]

Criteria: 17
Comment:
Pass: 3

Criteria: 18
SkipOver: True
Find: // {comment~}
Replace: [Skip over]

Criteria: 19
Find: ' {comment~}
Replace: // {comment}

Criteria: 20
BackColor: Green
PassOnce: False
Find: {nl}%{equate} = {value}
Replace: {nl}const int {equate} = {value};

Criteria: 21
BackColor: Green
Find: %{equate}
Replace: {equate}

Criteria: 22
BackColor: SandyBrown
Find: {"&h"}
Replace: 0x

Criteria: 23
BackColor: Green
PassOnce: False
Find: If {cond} Then {statement} [Else {else}]{nl}
Replace: if ({cond}) { {statement} }{else: else {{else}}}{nl}

Criteria: 24
PassOnce: False
Find: If {cond} Then {nl}
         {code+}
      End If
Replace: if ({cond}) {
            {code}
         }

Criteria: 25
BackColor: DarkKhaki
PassOnce: False
Find: Function {name} ([{args}]) As {type}{nl}
         {code+}
      End Function
Replace: {type} {name}({args}) {
            {code}
         !!ReleaseDynamicArrays!!}

Criteria: 26
PassOnce: False
Find: Sub {name} ([{args}]){nl}
         {code+}
      End Sub
Replace: void {name}({args}) {
            {code}
         !!ReleaseDynamicArrays!!}

Criteria: 27
PassOnce: False
Find: For {x} = {start} To {stop} [Step {inc=1}]{nl}
         {code+}
      Next
Replace: for ({x}={start}; {x}{@Eval: IIF(sgn({inc})>0, '<', '>')}={stop}; {x} += {inc}) {
            {code}
         }

Criteria: 28
PassOnce: False
Find: While {cond} {nl}
         {code+}
      Wend
Replace: while ({cond}) {
            {code}
         }

Criteria: 29
Find: !!ReleaseDynamicArrays!!
Replace: {@Eval:
            CleanUp = ""
            uc_For(x, 1, Count(ArrayNames), 1,
               Array = ReadKey(ArrayNames, x)
               CleanUp=CleanUp+"delete[] "+Array+";{nl}"
               Delete(ArrayNames, Array)
            )
            CleanUp
         }

Criteria: 30
BackColor: Orange
PassOnce: False
Find: { Dim | {member: {nl}}} {var:1} As {type} [{ptr: Ptr}]
Replace: {member: {nl}}{type} {ptr:*}{var};

Criteria: 31
PassOnce: False
Find: {nl} {bitfield:1} As Bit * {size} [{in: In {type}}]
Replace: {nl}{@Eval:
            IIf("{type}" <> "", SetVar(BitType, "{type}"))
            BitType
         } {bitfield} : {size};

Criteria: 32
PassOnce: False
Find: Dim {array}({subscript}) As {type}
Replace: {type} *{array} = new {type} [{subscript}+1];{@Eval:
            Insert(ArrayNames, "{array}")
         }{@Define:: Syntax: {array}({index}) ::= {array}[{index}]}

Criteria: 33
BackColor: SandyBrown
PassOnce: False
Find: Dim {var1}, {more}
Replace: Dim {var1}
         Dim {more}

Criteria: 34
BackColor: Gold
PassOnce: False
Find: { Local | Global | Register }
Replace: Dim

Criteria: 35
Find: @
Replace: *

Criteria: 36
BackColor: Silver
Find: VarPtr({var})
Replace: &{var}

Criteria: 37
BackColor: DeepSkyBlue
PassOnce: False
Find: Function = {value}
Replace: return {value};

Criteria: 38
BackColor: Lime
Find: Long
Replace: long

Criteria: 39
BackColor: Red
Find: Single
Replace: float

Criteria: 40
Find: Double
Replace: double

Criteria: 41
Find: Byte
Replace: unsigned char

Criteria: 42
Find: Integer
Replace: short

Criteria: 43
Find: Word
Replace: unsigned short

Criteria: 44
Find: Dword
Replace: unsigned long

Criteria: 45
BackColor: SlateBlue
PassOnce: False
Find: ByRef {arg} As {type:1}
Replace: {type}& {arg}

Criteria: 46
BackColor: Pink
PassOnce: False
Find: ByVal {arg} As {type:1} [{ptr: Ptr}]
Replace: {type} {ptr:*}{arg}

Criteria: 47
PassOnce: False
Find: Type {name:1}
         {members+}
      End Type
Replace: struct {name} {
            {members}
         }

Criteria: 48
Find: #If
Replace: #if

Criteria: 49
Find: #Else
Replace: #else

Criteria: 50
Find: #ElseIf
Replace: #elif

Criteria: 51
Find: #EndIf
Replace: #endif

Criteria: 52
PassOnce: False
Find: [{NOT: Not }] %Def({const})
Replace: {NOT:!}defined {const}

Criteria: 53
Comment: Adds semi-colons to statements
Pass: 4

Criteria: 54
SkipOver: True
Find: { "{" | "}" | ; | //{".*"} | #{".*"} } {nl} [{"[ \n]+"}]
Replace: [Skip over]

Criteria: 55
Comment: Skips over so that colons in bit fields are not affected
SkipOver: True
Find: struct {name:1} "{" {members+} "}"
Replace: [Skip over]

Criteria: 56
Find: :
Replace: ;

Criteria: 57
PassOnce: False
Find: {nl}
Replace: ;{nl}

# End Search


Update pb-to-cpp.uc

Update pb-to-cpp.uc

Several small fixes

# pb-to-cpp.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.95 on 4/23/2014 3:17:38 PM
# Comment: Converts PB source code to C++; modified by Daniel Corbier

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, InputFile, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique, FilterTally

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: True
Exclude: False
Comment: Converts PB source code to C++; modified by Daniel Corbier
Selected: False
Highlight: False
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: True
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
FilterTally: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
InputFile:
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
Find:
Replace: {@Define:
            Var: BitType As String
            Var: Case1
         }
         {@Define::
            Token: \xFF[^\xFF]*\xFF\n ~~ Properties: ucWhiteSpace
         }

Criteria: 2
Highlight: True
Find: {@Start}
Replace: ' This file ({@Eval: Extract(ShortName(InputFile), ".")}.cpp) was converted from {@Eval: Extract(ShortName(InputFile), ".")}.Bas
         ' with {@Eval: AppName} on {@Eval: TimeStamp("MM/dd/yy")} using the Open Source
         ' PowerBASIC to C++ converter found at https://github.com/uCalc/powerbasic-to-cpp

         #include "pbOS.h"
         #include "pbMisc.h"
         #include <cstdarg>

Criteria: 3
Comment: Renames words that conflict w/ C++ keywords
Pass: 1

Criteria: 4
Find: { auto|bitand|bitor|bool|break|char|compl|constexpr|
      continue|default|delete|explicit|extern|false|float|
      friend|inline|mutable|new|nullptr|operator|private|
      protected|public|short|signed|struct|template|this|
      throw|true|typename|unsigned|virtual|void|volatile }
Replace: {Self}_Renamed

Criteria: 5
SkipOver: True
Find: { ' | _ } {Comment:".*"}
Replace: [Skip over]

Criteria: 6
Comment: Handles long line break (underscore _)
Pass: 2

Criteria: 7
Highlight: True
PassOnce: False
Find: {nl}{line} _ [{" +"}] [{comment:".+"}]{nl}

Replace: {nl}{line} {#255}{comment}{#255}{nl}

Criteria: 8
Highlight: True
SkipOver: True
Find: {"[\(\)]"} {@Note: These are ( and ); must be skipped}
Replace: [Skip over]

Criteria: 9
Highlight: True
SkipOver: True
Find: ' [{comment:".*"}]
Replace: [Skip over]

Criteria: 10
Comment: Functions, Subs, =
Pass: 3

Criteria: 11
Highlight: True
Find: =
Replace: ==

Criteria: 12
SkipOver: True
Find: { + | - | * | / | % | & | ^ | ! }=
Replace: [Skip over]

Criteria: 13
Highlight: True
SkipOver: True
Find: { {nl}[{ %|$ }]|Then|Else|For|: } {var:" *[a-z0-9\@\.\_]+"}[({index})] =
Replace: [Skip over]

Criteria: 14
Highlight: True
SkipOver: True
Find: { { #If | #ElseIf } Not | ' [{comment:".*"}] }
Replace: [Skip over]

Criteria: 15
Highlight: True
SkipOver: True
Find: Macro {name}[({params})] =
Replace: [Skip over]

Criteria: 16
Highlight: True
PassOnce: False
Find: Sub {name:1} [Alias {alias}]([{args}])[{exp: Export}] [{comment:" *'.*"}] {nl}
Replace: {exp:extern "C" __declspec(dllexport)} void {exp:__stdcall} {name}({args}) { {comment}

Criteria: 17
Highlight: True
BackColor: DarkKhaki
PassOnce: False
Find: Function {name:1} [Alias {alias}]([{args}])[{exp: Export}] As {type}[{comment:" *'.*"}]{nl}
Replace: {exp:extern "C" __declspec(dllexport)} {type} {exp:__stdcall} {name}({args}) { {comment}
         {@Define:: Syntax: {name} = ::= return{#32}}

Criteria: 18
Highlight: True
PassOnce: False
Find: Function PBMain [()] [As Long]
Replace: Function main() As Long

Criteria: 19
Highlight: True
PassOnce: False
Find: Declare Function {name:1} [Lib {lib}] [Alias {alias}]
      [([{args}])] As {type}
Replace: {lib: extern __declspec(dllimport)} {type} {name}({args})

Criteria: 20
Highlight: True
Find: Declare Sub {name:1} [Lib {lib}] [Alias {alias}]
      [([{args}])]
Replace: {lib: extern __declspec(dllimport)} void {name}({args})

Criteria: 21
Highlight: True
Find: Static
Replace: static dim

Criteria: 22
Comment: For type member access (temp stage)
Find: {typevar:"@*[a-z_][a-z_0-9@]+\.[a-z_0-9@\.]+"}
Replace: `{typevar}`

Criteria: 23
Comment: Misc
Pass: 4

Criteria: 24
Highlight: True
SkipOver: True
Find: // [{comment:".*"}]
Replace: [Skip over]

Criteria: 25
Highlight: True
Find: ' [{comment:".*"}]
Replace: //{comment}

Criteria: 26
Highlight: True
BackColor: Green
PassOnce: False
Find: {nl}{ {num: %} | {str: $} }{equate} = {value}
Replace: {nl}const{num: int}{str: string} {equate} = {value};

Criteria: 27
Highlight: True
BackColor: Green
Find: { % | $ }{equate:"[a-z]+"}
Replace: {equate}

Criteria: 28
Highlight: True
BackColor: SandyBrown
Find: {"&h"}
Replace: 0x

Criteria: 29
Comment: Single-line IF
Highlight: True
BackColor: Green
PassOnce: False
Find: If {cond} Then {statement} [Else {else}]{nl}
Replace: if ({cond}) {{statement}{nl}}{else: else {{else}{nl}}}{nl}

Criteria: 30
Comment: Multi-line IF
Highlight: True
PassOnce: False
Find: If {cond} Then [{comment:" *'.*"}] {nl}
Replace: if ({cond}) { {comment}{nl}

Criteria: 31
Find: {nl}Else
Replace: {nl} } else {

Criteria: 32
Find: {nl}ElseIf {cond} Then
Replace: {nl} } else if ({cond}) {

Criteria: 33
Highlight: True
PassOnce: False
Find: For {x} = {start} To {stop} [Step {inc=1}][{comment:" *'.*"}]
Replace: for ({x}={start}; {x}{@Eval: IIF(sgn({inc})>0, '<', '>')}={stop}; {x} += {inc}) { {comment}

Criteria: 34
Highlight: True
PassOnce: False
Find: {nl}While {cond} [{comment:" *'.*"}] {nl}
Replace: {nl}while ({cond}) { {comment} {nl}

Criteria: 35
Highlight: True
PassOnce: False
Find: Do { {while: While} | {until: Until} } {cond} [{comment:" *'.*"}]{nl}
Replace: while ({while: {cond}}{until:!({cond})}) { {comment}

Criteria: 36
Find: { End { Sub|Function|If|Type|Union } | Wend|Next|Loop }
Replace: }

Criteria: 37
Find: do{nl}
Replace: do {

Criteria: 38
Highlight: True
PassOnce: False
Find: Loop { {while: While} | {until: Until} } {cond} [{comment:" *'.*"}]
Replace: } while ({while: {cond}}{until:!({cond})}) {comment}

Criteria: 39
Find: Select Case [As] [Long | Const | Const$] {expr} {nl}
Replace: { auto CASE_VAR = {expr}
         {@Execute: Case1 = 1}

Criteria: 40
Find: End Select
Replace: }}

Criteria: 41
Find: Case [IS] {test%} [:] [' {comment:".*"}]
Replace: {@Evaluate:
            IIf(Case1==1, Case1=0; "", "} else")
         } if (CASE_VAR == {test}) {{comment: // {comment}}

Criteria: 42
PassOnce: False
Find: Case [IS] {item}, {more}
Replace: Case {item} || CASE_VAR = {more}

Criteria: 43
Find: Case Else
Replace: } else {

Criteria: 44
Highlight: True
BackColor: Orange
PassOnce: False
Find: { Dim | {member: {nl}}} {var:1} As {type:1} [{ptr: Ptr}]
Replace: {member: {nl}}{type} {ptr:*}{var};

Criteria: 45
Highlight: True
PassOnce: False
Find: {nl} {bitfield:1} As Bit * {size:1} [{in: In {type:1}}]
Replace: {nl}{@Eval:
            IIf("{type}" <> "", SetVar(BitType, "{type}"))
            BitType
         } {bitfield} : {size};

Criteria: 46
Highlight: True
PassOnce: False
Find: Dim {array}([{size}]) As {type}
Replace: std::vector<{type}> {array}{size: ({size}+1)};{@Define::
             Syntax: {array}([{sz}]) ::= {array}[{sz}]}

Criteria: 47
Find: Erase {array:1}[()]
Replace: {array}.clear();

Criteria: 48
PassOnce: False
Find: ReDim {array}({size}) [As {type}] [{more: , {etc}}]
Replace: {array}.clear();
         {array}.resize({size}+1); {more: {nl} ReDim {etc}}

Criteria: 49
PassOnce: False
Find: ReDim Preserve {array}({size}) [As {type}] [{more: , {etc}}]
Replace: {array}.resize({size}+1); {more: {nl} ReDim Preserve {etc}}

Criteria: 50
Find: UBound({array})
Replace: ({array}.size()-1)

Criteria: 51
Highlight: True
BackColor: SandyBrown
PassOnce: False
Find: Dim {var1}, {more}
Replace: Dim {var1}
         Dim {more}

Criteria: 52
Highlight: True
BackColor: Gold
PassOnce: False
Find: { Local | Global | Register }
Replace: Dim

Criteria: 53
Find: `{typevar}.@{last:1}`
Replace: *`{typevar}.{last}`

Criteria: 54
Highlight: True
BackColor: Silver
Find: VarPtr({var})
Replace: &{var}

Criteria: 55
Find: Iterate
Replace: continue

Criteria: 56
Find: Exit
Replace: break

Criteria: 57
Highlight: True
Find: Exit Sub
Replace: return

Criteria: 58
Highlight: True
BackColor: Lime
Find: Long
Replace: int

Criteria: 59
Highlight: True
BackColor: Red
Find: Single
Replace: float

Criteria: 60
Find: Double
Replace: double

Criteria: 61
Highlight: True
Find: Byte
Replace: unsigned char

Criteria: 62
Highlight: True
Find: Integer
Replace: short

Criteria: 63
Highlight: True
Find: Word
Replace: unsigned short

Criteria: 64
Highlight: True
Find: Dword
Replace: unsigned int

Criteria: 65
Find: AsciiZ
Replace: LPCSTR

Criteria: 66
Highlight: True
Find: Quad
Replace: __int64

Criteria: 67
SkipOver: True
Find: long double
Replace: [Skip over]

Criteria: 68
Highlight: True
Find: { Extended | Ext }
Replace: long double

Criteria: 69
Highlight: True
BackColor: SlateBlue
PassOnce: False
Find: ByRef {arg} As {type:1}
Replace: {type}& {arg}

Criteria: 70
PassOnce: False
Find: ByRef {array}() As {type:1}
Replace: {type} {array}[]{@Define::
            Syntax: {array}([{index}]) ::= {array}[{index}]
         }

Criteria: 71
Highlight: True
BackColor: Pink
PassOnce: False
Find: ByVal {arg} As {type:1} [{ptr: Ptr}]
Replace: {type} {ptr:*}{arg}

Criteria: 72
Find: Type {name:1}
Replace: struct {name} {

Criteria: 73
Find: Union {name:1}
Replace: union {name} {

Criteria: 74
Highlight: True
Find: Macro {name} [{params: ({paramlist})}] = {replacement%}
Replace: #define {name}{params} {replacement}

Criteria: 75
Highlight: True
Find: #ElseIf
Replace: #elif

Criteria: 76
Find: #{directive: If | Else | EndIf }
Replace: #{@Eval: LCase("{directive}", "{'.*'}")}

Criteria: 77
Highlight: True
PassOnce: False
Find: [{NOT: Not }] %Def({const})
Replace: {NOT:!}defined {const}

Criteria: 78
PassOnce: False
Find: Choose[&]({index}, {choice})
Replace: IIf({index}, {choice}, 0)

Criteria: 79
PassOnce: False
Find: Choose$({index}, {choice})
Replace: IIf({index}, {choice}, "")

Criteria: 80
PassOnce: False
Find: Choose[{type: $ | & }]({index}, {choice1}, {more})
Replace: IIf({index}, {choice1}, Choose{type}({index}, {more}))

Criteria: 81
Find: StdOut {text} { {sameline: ;} | {NewLine: } }
Replace: cout << {text} {NewLine: << endl;}

Criteria: 82
Find: Sleep {milliseconds}
Replace: PB_SLEEP({milliseconds})

Criteria: 83
Find: {keyword:"CV(BYT|DWD|D|E|I|L|Q|S|WRD)"}({string} [, {offset=1}])
Replace: PB_{@Eval:UCase("{keyword}", "{'.*'}")}({string}, {offset})

Criteria: 84
PassOnce: False
Find: Line Input [{prompt: {q}{str}{q} | ${equate:1}}][,] {StrVariable:1}
Replace: {prompt: cout << {prompt};}getline(cin, {StrVariable});

Criteria: 85
PassOnce: False
Find: IIf[$]({cond}, {this}, {that})
Replace: ({cond} ? {this} : {that})

Criteria: 86
Find: PB_ASC({q}{char}{q}, {n:" *[0-9]+"})
Replace: '{@Eval:Mid("{char}", {n}, 1, ucChar)}'

Criteria: 87
Find: _char([{char= }])
Replace: '{char}'

Criteria: 88
Highlight: True
BackColor: DeepSkyBlue
PassOnce: False
Find: Function = {value}
Replace: return {value}

Criteria: 89
Comment: Adds semi-colons to statements, etc
Pass: 5

Criteria: 90
Highlight: True
SkipOver: True
Find: { "{" | "}" | ; | //[{".*"}] | #{".*"} } {nl} [{"[ \n]+"}]
Replace: [Skip over]

Criteria: 91
Comment: Skips over so that colons in bit fields are not affected
Highlight: True
SkipOver: True
Find: { struct | union } {name:1} "{" {members+} "}"
Replace: [Skip over]

Criteria: 92
Selected: True
SkipOver: True
Find: ? {ternaryIF} :
Replace: [Skip over]

Criteria: 93
Highlight: True
Find: :
Replace: ;

Criteria: 94
SkipOver: True
Find: ::
Replace: [Skip over]

Criteria: 95
Highlight: True
PassOnce: False
Find: {nl}
Replace: ;{nl}

Criteria: 96
Comment: Misc
Pass: 6

Criteria: 97
Find: {" \xFF\xFF\n"}
Replace: {nl}

Criteria: 98
Find: {" \xFF"}{comment:"[^\xFF]+"}{"\xFF\n"}
Replace:  /* {comment} */{nl}

Criteria: 99
Find: @
Replace: *

Criteria: 100
Highlight: True
Find: @{pointer:1}.
Replace: {pointer}->

Criteria: 101
Find: `{@Comment: removes temp char for type member access}
Replace: {Nothing}

# End Search

# pb-to-cpp.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.95 on 4/18/2014 5:15:23 PM
# Comment: Converts PB source code to C++; modified by Daniel Corbier

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, InputFile, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique, FilterTally

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: True
Exclude: False
Comment: Converts PB source code to C++; modified by Daniel Corbier
Selected: False
Highlight: False
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: True
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
FilterTally: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
InputFile:
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
Find:
Replace: {@Define:
            Var: BitType As String
            Var: Case1
         }
         {@Define::
            Token: \xFF[^\xFF]*\xFF\n ~~ Properties: ucWhiteSpace
         }

Criteria: 2
Highlight: True
Find: {@Start}
Replace: ' This file ({@Eval: Extract(ShortName(InputFile), ".")}.cpp) was converted from {@Eval: Extract(ShortName(InputFile), ".")}.Bas
         ' with {@Eval: AppName} on {@Eval: TimeStamp("MM/dd/yy")} using the Open Source
         ' PowerBASIC to C++ converter found at https://github.com/uCalc/powerbasic-to-cpp

         #include "pbOS.h"
         #include "pbMisc.h"
         #include <cstdarg>

Criteria: 3
Comment: Renames words that conflict w/ C++ keywords
Pass: 1

Criteria: 4
Find: { auto|bitand|bitor|bool|break|char|compl|constexpr|
      continue|default|delete|explicit|extern|false|float|
      friend|inline|mutable|new|nullptr|operator|private|
      protected|public|short|signed|struct|template|this|
      throw|true|typename|unsigned|virtual|void|volatile }
Replace: {Self}_Renamed

Criteria: 5
SkipOver: True
Find: { ' | _ } {Comment:".*"}
Replace: [Skip over]

Criteria: 6
Comment: Handles long line break (underscore _)
Pass: 2

Criteria: 7
Highlight: True
PassOnce: False
Find: {nl}{line} _ [{" +"}] [{comment:".+"}]{nl}

Replace: {nl}{line} {#255}{comment}{#255}{nl}

Criteria: 8
Highlight: True
SkipOver: True
Find: {"[\(\)]"} {@Note: These are ( and ); must be skipped}
Replace: [Skip over]

Criteria: 9
Highlight: True
SkipOver: True
Find: ' [{comment:".*"}]
Replace: [Skip over]

Criteria: 10
Comment: Functions, Subs, =
Pass: 3

Criteria: 11
Highlight: True
Find: =
Replace: ==

Criteria: 12
SkipOver: True
Find: { + | - | * | / | % | & | ^ | ! }=
Replace: [Skip over]

Criteria: 13
Highlight: True
SkipOver: True
Find: { {nl}[{ %|$ }]|Then|Else|For|: } {var:" *[a-z\@\.\_]+"}[({index})] =
Replace: [Skip over]

Criteria: 14
Highlight: True
SkipOver: True
Find: { { #If | #ElseIf } Not | ' [{comment:".*"}] }
Replace: [Skip over]

Criteria: 15
Highlight: True
SkipOver: True
Find: Macro {name}[({params})] =
Replace: [Skip over]

Criteria: 16
Highlight: True
PassOnce: False
Find: Sub {name:1} [Alias {alias}]([{args}])[{exp: Export}] [{comment:" *'.*"}] {nl}
Replace: {exp:extern "C" __declspec(dllexport)} void {exp:__stdcall} {name}({args}) { {comment}

Criteria: 17
Highlight: True
BackColor: DarkKhaki
PassOnce: False
Find: Function {name:1} [Alias {alias}]([{args}])[{exp: Export}] As {type}[{comment:" *'.*"}]{nl}
Replace: {exp:extern "C" __declspec(dllexport)} {type} {exp:__stdcall} {name}({args}) { {comment}
         {@Define:: Syntax: {name} = ::= return{#32}}

Criteria: 18
Highlight: True
PassOnce: False
Find: Function PBMain [()] [As Long]
Replace: Function main() As Long

Criteria: 19
Highlight: True
PassOnce: False
Find: Declare Function {name:1} [Lib {lib}] [Alias {alias}]
      [([{args}])] As {type}
Replace: {lib: extern __declspec(dllimport)} {type} {name}({args})

Criteria: 20
Highlight: True
Find: Declare Sub {name:1} [Lib {lib}] [Alias {alias}]
      [([{args}])]
Replace: {lib: extern __declspec(dllimport)} void {name}({args})

Criteria: 21
Highlight: True
Find: Static
Replace: static dim

Criteria: 22
Comment: For type member access (temp stage)
Find: {typevar:"@*[a-z_][a-z_0-9@]+\.[a-z_0-9@\.]+"}
Replace: `{typevar}`

Criteria: 23
Comment: Misc
Pass: 4

Criteria: 24
Highlight: True
SkipOver: True
Find: // [{comment:".*"}]
Replace: [Skip over]

Criteria: 25
Highlight: True
Find: ' [{comment:".*"}]
Replace: //{comment}

Criteria: 26
Highlight: True
BackColor: Green
PassOnce: False
Find: {nl}{ {num: %} | {str: $} }{equate} = {value}
Replace: {nl}const{num: int}{str: string} {equate} = {value};

Criteria: 27
Highlight: True
BackColor: Green
Find: { % | $ }{equate:"[a-z]+"}
Replace: {equate}

Criteria: 28
Highlight: True
BackColor: SandyBrown
Find: {"&h"}
Replace: 0x

Criteria: 29
Comment: Single-line IF
Highlight: True
BackColor: Green
PassOnce: False
Find: If {cond} Then {statement} [Else {else}]{nl}
Replace: if ({cond}) {{statement}{nl}}{else: else {{else}{nl}}}{nl}

Criteria: 30
Comment: Multi-line IF
Highlight: True
PassOnce: False
Find: If {cond} Then [{comment:" *'.*"}] {nl}
Replace: if ({cond}) { {comment}{nl}

Criteria: 31
Find: {nl}Else
Replace: {nl} } else {

Criteria: 32
Find: {nl}ElseIf {cond} Then
Replace: {nl} } else if ({cond}) {

Criteria: 33
Highlight: True
PassOnce: False
Find: For {x} = {start} To {stop} [Step {inc=1}][{comment:" *'.*"}]
Replace: for ({x}={start}; {x}{@Eval: IIF(sgn({inc})>0, '<', '>')}={stop}; {x} += {inc}) { {comment}

Criteria: 34
Highlight: True
PassOnce: False
Find: {nl}While {cond} [{comment:" *'.*"}] {nl}
Replace: {nl}while ({cond}) { {comment} {nl}

Criteria: 35
Highlight: True
PassOnce: False
Find: Do { {while: While} | {until: Until} } {cond} [{comment:" *'.*"}]{nl}
Replace: while ({while: {cond}}{until:!({cond})}) { {comment}

Criteria: 36
Find: { End { Sub|Function|If|Type|Union } | Wend|Next|Loop }
Replace: }

Criteria: 37
Find: do{nl}
Replace: do {

Criteria: 38
Highlight: True
PassOnce: False
Find: Loop { {while: While} | {until: Until} } {cond} [{comment:" *'.*"}]
Replace: } while ({while: {cond}}{until:!({cond})}) {comment}

Criteria: 39
Find: Select Case [As] [Long | Const | Const$] {expr} {nl}
Replace: { auto CASE_VAR = {expr}
         {@Execute: Case1 = 1}

Criteria: 40
Find: End Select
Replace: }}

Criteria: 41
Find: Case [IS] {test%} [:] [' {comment:".*"}]
Replace: {@Evaluate:
            IIf(Case1==1, Case1=0; "", "} else")
         } if (CASE_VAR == {test}) {{comment: // {comment}}

Criteria: 42
PassOnce: False
Find: Case [IS] {item}, {more}
Replace: Case {item} || CASE_VAR = {more}

Criteria: 43
Find: Case Else
Replace: } else {

Criteria: 44
Highlight: True
BackColor: Orange
PassOnce: False
Find: { Dim | {member: {nl}}} {var:1} As {type} [{ptr: Ptr}]
Replace: {member: {nl}}{type} {ptr:*}{var};

Criteria: 45
Highlight: True
PassOnce: False
Find: {nl} {bitfield:1} As Bit * {size:1} [{in: In {type:1}}]
Replace: {nl}{@Eval:
            IIf("{type}" <> "", SetVar(BitType, "{type}"))
            BitType
         } {bitfield} : {size};

Criteria: 46
Highlight: True
PassOnce: False
Find: Dim {array}([{size}]) As {type}
Replace: std::vector<{type}> {array}{size: ({size}+1)};{@Define::
             Syntax: {array}([{sz}]) ::= {array}[{sz}]}

Criteria: 47
Find: Erase {array:1}[()]
Replace: {array}.clear();

Criteria: 48
PassOnce: False
Find: ReDim {array}({size}) [As {type}] [{more: , {etc}}]
Replace: {array}.clear();
         {array}.resize({size}+1); {more: {nl} ReDim {etc}}

Criteria: 49
PassOnce: False
Find: ReDim Preserve {array}({size}) [As {type}] [{more: , {etc}}]
Replace: {array}.resize({size}+1); {more: {nl} ReDim Preserve {etc}}

Criteria: 50
Find: UBound({array})
Replace: ({array}.size()-1)

Criteria: 51
Highlight: True
BackColor: SandyBrown
PassOnce: False
Find: Dim {var1}, {more}
Replace: Dim {var1}
         Dim {more}

Criteria: 52
Highlight: True
BackColor: Gold
PassOnce: False
Find: { Local | Global | Register }
Replace: Dim

Criteria: 53
Find: `{typevar}.@{last:1}`
Replace: *`{typevar}.{last}`

Criteria: 54
Highlight: True
BackColor: Silver
Find: VarPtr({var})
Replace: &{var}

Criteria: 55
Find: Iterate
Replace: continue

Criteria: 56
Find: Exit
Replace: break

Criteria: 57
Highlight: True
Find: Exit Sub
Replace: return

Criteria: 58
Highlight: True
BackColor: Lime
Find: Long
Replace: int

Criteria: 59
Highlight: True
BackColor: Red
Find: Single
Replace: float

Criteria: 60
Find: Double
Replace: double

Criteria: 61
Highlight: True
Find: Byte
Replace: unsigned char

Criteria: 62
Highlight: True
Find: Integer
Replace: short

Criteria: 63
Highlight: True
Find: Word
Replace: unsigned short

Criteria: 64
Highlight: True
Find: Dword
Replace: unsigned int

Criteria: 65
Find: AsciiZ
Replace: LPCSTR

Criteria: 66
Highlight: True
Find: Quad
Replace: __int64

Criteria: 67
SkipOver: True
Find: long double
Replace: [Skip over]

Criteria: 68
Highlight: True
Find: { Extended | Ext }
Replace: long double

Criteria: 69
Highlight: True
BackColor: SlateBlue
PassOnce: False
Find: ByRef {arg} As {type:1}
Replace: {type}& {arg}

Criteria: 70
PassOnce: False
Find: ByRef {array}() As {type:1}
Replace: {type} {array}[]{@Define::
            Syntax: {array}([{index}]) ::= {array}[{index}]
         }

Criteria: 71
Highlight: True
BackColor: Pink
PassOnce: False
Find: ByVal {arg} As {type:1} [{ptr: Ptr}]
Replace: {type} {ptr:*}{arg}

Criteria: 72
Find: Type {name:1}
Replace: struct {name} {

Criteria: 73
Find: Union {name:1}
Replace: union {name} {

Criteria: 74
Highlight: True
Find: Macro {name} [{params: ({paramlist})}] = {replacement%}
Replace: #define {name}{params} {replacement}

Criteria: 75
Highlight: True
Find: #ElseIf
Replace: #elif

Criteria: 76
Find: #{directive: If | Else | EndIf }
Replace: #{@Eval: LCase("{directive}", "{'.*'}")}

Criteria: 77
Highlight: True
PassOnce: False
Find: [{NOT: Not }] %Def({const})
Replace: {NOT:!}defined {const}

Criteria: 78
Find: Choose[&]({index}, {choice})
Replace: IIf({index}, {choice}, 0)

Criteria: 79
Find: Choose$({index}, {choice})
Replace: IIf({index}, {choice}, "")

Criteria: 80
PassOnce: False
Find: Choose[{type: $ | & }]({index}, {choice1}, {more})
Replace: IIf({index}, {choice1}, Choose{type}({index}, {more}))

Criteria: 81
Find: StdOut {text} { {sameline: ;} | {NewLine: } }
Replace: cout << {text} {NewLine: << endl;}

Criteria: 82
Find: Sleep {milliseconds}
Replace: PB_SLEEP({milliseconds})

Criteria: 83
Find: {keyword:"CV(BYT|DWD|D|E|I|L|Q|S|WRD)"}({string} [, {offset=1}])
Replace: PB_{@Eval:UCase("{keyword}", "{'.*'}")}({string}, {offset})

Criteria: 84
PassOnce: False
Find: Line Input [{prompt: {q}{str}{q} | ${equate:1}}][,] {StrVariable:1}
Replace: {prompt: cout << {prompt};}getline(cin, {StrVariable});

Criteria: 85
Comment: Adds semi-colons to statements, etc
Pass: 5

Criteria: 86
Highlight: True
SkipOver: True
Find: { "{" | "}" | ; | //[{".*"}] | #{".*"} } {nl} [{"[ \n]+"}]
Replace: [Skip over]

Criteria: 87
Comment: Skips over so that colons in bit fields are not affected
Highlight: True
SkipOver: True
Find: { struct | union } {name:1} "{" {members+} "}"
Replace: [Skip over]

Criteria: 88
SkipOver: True
Find: ({cond} ? {this} :
Replace: [Skip over]

Criteria: 89
Highlight: True
Find: :
Replace: ;

Criteria: 90
SkipOver: True
Find: ::
Replace: [Skip over]

Criteria: 91
Highlight: True
PassOnce: False
Find: {nl}
Replace: ;{nl}

Criteria: 92
PassOnce: False
Find: IIf[$]({cond%}, {this%}, {that%})
Replace: ({cond} ? {this} : {that})

Criteria: 93
Find: _char([{char= }])
Replace: '{char}'

Criteria: 94
Find: {" \xFF\xFF\n"}
Replace: {nl}

Criteria: 95
Find: {" \xFF"}{comment:"[^\xFF]+"}{"\xFF\n"}
Replace:  /* {comment} */{nl}

Criteria: 96
Highlight: True
BackColor: DeepSkyBlue
PassOnce: False
Find: Function = {value}
Replace: return {value}

Criteria: 97
Find: PB_ASC({q}{char}{q}, {n:" *[0-9]+"})
Replace: '{@Eval:Mid("{char}", {n}, 1, ucChar)}'

Criteria: 98
Find: @
Replace: *

Criteria: 99
Selected: True
Highlight: True
Find: @{pointer:1}.
Replace: {pointer}->

Criteria: 100
Find: `{@Comment: removes temp char for type member access}
Replace: {Nothing}

# End Search


Update pb-to-cpp.uc

Update pb-to-cpp.uc

Update to pb-to-cpp.uc (#If/#Else/#ElseIf/#EndIf/%Def(), etc)

# convert.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.0 on 12/17/2013 2:30:45 PM
# Comment: Converts PB source code to C++; modified by Daniel Corbier

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: True
Exclude: False
Comment: Converts PB source code to C++; modified by Daniel Corbier
Selected: False
Highlight: True
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: True
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
Find:
Replace: {@Define:
            Var: Array As String
            Var: ArrayNames As Table
            Var: CleanUp As String
         }

Criteria: 2
SkipOver: True
Find: // {comment~}
Replace: [Skip over]

Criteria: 3
Find: ' {comment~}
Replace: // {comment}

Criteria: 4
BackColor: Green
Find: {nl}%{equate} = {value%}
Replace: {nl}const int {equate} = {value};

Criteria: 5
BackColor: Green
Find: %{equate}
Replace: {equate}

Criteria: 6
BackColor: SandyBrown
Find: {"&h"}
Replace: 0x

Criteria: 7
BackColor: Green
Find: If {cond%} Then {statement%}{nl}
Replace: if ({cond}) { {statement} }{nl}

Criteria: 8
Find: If {cond%} Then {nl}
         {code%+}
      End If
Replace: if ({cond}) {
            {code}
         }

Criteria: 9
BackColor: DarkKhaki
PassOnce: False
Find: Function {name} ([{args}]) As {type}{nl}
         {code%+}
      End Function
Replace: {type} {name}({args}) {
            {code}
         !!ReleaseDynamicArrays!!}

Criteria: 10
PassOnce: False
Find: Sub {name} ([{args}]){nl}
         {code%+}
      End Sub
Replace: void {name}({args}) {
            {code}
         !!ReleaseDynamicArrays!!}

Criteria: 11
Find: For {x} = {start} To {stop} [Step {inc=1}]{nl}
         {code+}
      Next
Replace: for ({x}={start}; {x}{@Eval: IIF(sgn({inc})>0, '<', '>')}={stop}; {x} += {inc}) {
            {code}
         }

Criteria: 12
Find: While {cond%} {nl}
         {code+}
      Wend
Replace: while ({cond}) {
            {code}
         }

Criteria: 13
Find: !!ReleaseDynamicArrays!!
Replace: {@Eval:
            CleanUp = ""
            Array = ReadKey(ArrayNames, x)
            uc_For(x, 1, Count(ArrayNames), 1,
               CleanUp=CleanUp+"delete[] "+Array+";{nl}"
               Delete(ArrayNames, Array)
            )
            CleanUp
         }

Criteria: 14
BackColor: Orange
Find: { Dim | {member: {nl}}} {var:1} As {type%} [{ptr: Ptr}]
Replace: {member: {nl}}{type} {ptr:*}{var};

Criteria: 15
Find: Dim {array}({subscript}) As {type%}
Replace: {type} *{array} = new {type} [{subscript}+1];{@Eval:
            Insert(ArrayNames, "{array}")
         }{@Define:: Syntax: {array}({index}) ::= {array}[{index}]}

Criteria: 16
BackColor: SandyBrown
PassOnce: False
Find: Dim {var1}, {more}
Replace: Dim {var1}
         Dim {more}

Criteria: 17
BackColor: Gold
PassOnce: False
Find: { Local | Global | Register }
Replace: Dim

Criteria: 18
Find: @
Replace: *

Criteria: 19
BackColor: Silver
Find: VarPtr({var})
Replace: &{var}

Criteria: 20
BackColor: DeepSkyBlue
Find: Function = {value%}
Replace: return {value};

Criteria: 21
BackColor: Lime
Find: Long
Replace: long

Criteria: 22
BackColor: Red
Find: Single
Replace: float

Criteria: 23
Find: Double
Replace: double

Criteria: 24
BackColor: SlateBlue
Find: ByRef {arg} As {type%:1}
Replace: {type}& {arg}

Criteria: 25
BackColor: Pink
Find: ByVal {arg} As {type%:1}
Replace: {type} {arg}

Criteria: 26
Find: Type {name:1}
         {members%+}
      End Type
Replace: struct {name} {
            {members}
         }

Criteria: 27
Find: #If
Replace: #if

Criteria: 28
Find: #Else
Replace: #else

Criteria: 29
Find: #ElseIf
Replace: #elif

Criteria: 30
Find: #EndIf
Replace: #endif

Criteria: 31
Selected: True
Find: [{NOT: Not }] %Def({const%})
Replace: {NOT:!}defined {const}

# End Search

# convert.uc - uCalc Transformation file
# This file was saved with uCalc Transform 2.0 on 12/16/2013 9:05:30 AM
# Comment: Converts PB source code to C++; modified by Daniel Corbier

ExternalKeywords: Exclude, Comment, Selected, ParentChild, FindMode, OutputFile, BatchAction, SEND
ExternalKeywords: Highlight, ForeColor, BackColor, FontName, FontSize, FontStyle
ExternalKeywords: FilterEndText, FilterSeparator, FilterSort, FilterSortFunc, FilterStartText, FilterUnique

FindMode: Replace

# Definitions

# Search Criteria

Criteria: 0
Enabled: True
Exclude: False
Comment: Converts PB source code to C++; modified by Daniel Corbier
Selected: False
Highlight: True
ForeColor: ControlText
BackColor: Aqua
FontName:
FontSize:
FontStyle:
CaseSensitive: False
QuoteSensitive: True
CodeBlockSensitive: True
FilterEndText:
FilterSeparator: {#10}
FilterSort: False
FilterSortFunc:
FilterStartText:
FilterUnique: False
Min: 0
Max: -1
MinSoft: 0
MaxSoft: -1
BatchAction: Transform
OutputFile:
SEND:
StartAfter: 0
StopAfter: -1
SkipOver: False
ParentChild: 0
Pass: 0
PassOnce: True
Precedence: 0
RightToLeft: False

Criteria: 1
Find:
Replace: {@Define:
            Var: Array As String
            Var: ArrayNames As Table
            Var: CleanUp As String
         }

Criteria: 2
SkipOver: True
Find: // {comment~}
Replace: [Skip over]

Criteria: 3
Find: ' {comment~}
Replace: // {comment}

Criteria: 4
BackColor: Green
Find: {nl}%{equate} = {value%}
Replace: {nl}const int {equate} = {value};

Criteria: 5
BackColor: Green
Find: %{equate}
Replace: {equate}

Criteria: 6
BackColor: SandyBrown
Find: {"&h"}
Replace: 0x

Criteria: 7
BackColor: Green
Find: If {cond%} Then {statement%}{nl}
Replace: if ({cond}) { {statement} }{nl}

Criteria: 8
Find: If {cond%} Then {nl}
         {code%+}
      End If
Replace: if ({cond}) {
            {code}
         }

Criteria: 9
BackColor: DarkKhaki
PassOnce: False
Find: Function {name} ([{args}]) As {type}{nl}
         {code%+}
      End Function
Replace: {type} {name}({args}) {
            {code}
         !!ReleaseDynamicArrays!!}

Criteria: 10
PassOnce: False
Find: Sub {name} ([{args}]){nl}
         {code%+}
      End Sub
Replace: void {name}({args}) {
            {code}
         !!ReleaseDynamicArrays!!}

Criteria: 11
Find: For {x} = {start} To {stop} [Step {inc=1}]{nl}
         {code+}
      Next
Replace: for ({x}={start}; {x}{@Eval: IIF(sgn({inc})>0, '<', '>')}={stop}; {x} += {inc}) {
            {code}
         }

Criteria: 12
Find: While {cond%} {nl}
         {code+}
      Wend
Replace: while ({cond}) {
            {code}
         }

Criteria: 13
Find: !!ReleaseDynamicArrays!!
Replace: {@Eval:
            CleanUp = ""
            Array = ReadKey(ArrayNames, x)
            uc_For(x, 1, Count(ArrayNames), 1,
               CleanUp=CleanUp+"delete[] "+Array+";{nl}"
               Delete(ArrayNames, Array)
            )
            CleanUp
         }

Criteria: 14
BackColor: Orange
Find: { Dim | {member: {nl}}} {var:1} As {type%} [{ptr: Ptr}]
Replace: {member: {nl}}{type} {ptr:*}{var};

Criteria: 15
Selected: True
Find: Dim {array}({subscript}) As {type%}
Replace: {type} *{array} = new {type} [{subscript}+1];{@Eval:
            Insert(ArrayNames, "{array}")
         }{@Define:: Syntax: {array}({index}) ::= {array}[{index}]}

Criteria: 16
BackColor: SandyBrown
PassOnce: False
Find: Dim {var1}, {more}
Replace: Dim {var1}
         Dim {more}

Criteria: 17
BackColor: Gold
PassOnce: False
Find: { Local | Global | Register }
Replace: Dim

Criteria: 18
Find: @
Replace: *

Criteria: 19
BackColor: Silver
Find: VarPtr({var})
Replace: &{var}

Criteria: 20
BackColor: DeepSkyBlue
Find: Function = {value%}
Replace: return {value};

Criteria: 21
BackColor: Lime
Find: Long
Replace: long

Criteria: 22
BackColor: Red
Find: Single
Replace: float

Criteria: 23
BackColor: SlateBlue
Find: ByRef {arg} As {type%:1}
Replace: {type}& {arg}

Criteria: 24
BackColor: Pink
Find: ByVal {arg} As {type%:1}
Replace: {type} {arg}

Criteria: 25
Find: Type {name:1}
         {members%+}
      End Type
Replace: struct {name} {
            {members}
         }

# End Search


ensure a motd source uses unix style line endings

class Core extends SwatGame.SwatMutator
 implements HTTP.ClientOwner;

/**
 * Copyright (c) 2014 Sergei Khoroshilov <kh.sergei@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

import enum eClientError from HTTP.Client;

/**
 * MOTD package version
 * @type string
 */
const VERSION = "1.1.0";

/**
 * Fixed tick rate (seconds)
 * @type float
 */
const DELTA = 0.5;

/**
 * Max message block length
 * @type int
 */
const MAX_BLOCK_LENGTH = 1024;

/**
 * Message block delimiter
 * @type string
 */
const BLOCK_DELIMITER = "\n\n";

/**
 * Header block delimiter
 * @type string
 */
const HEADER_DELIMITER = "\n";

/**
 * Message options delimiter
 * @type string
 */
const OPTION_DELIMITER = "\t";

/**
 * Message Block structure:
 *     Option1 $ OPTION_DELIMITER $ Option2 $ OPTION_DELIMITER $ Option3 $ HEADER_DELIMITER $ Line1\nLine2\n $ BLOCK_DELIMITER
 *
 * Example:
 *     60\t0\t*
 *     Welcome to the server!
 *     Please follow the rules and have fun.
 *
 *     65\t120\t*
 *     Visit us at example.com
 */

struct sMotdMessage
{
    /**
     * MOTD message
     * @type string
     */
    var string Message;

    /**
     * Initial message delay since level startup (in seconds) (Internal counter)
     * @type int
     */
    var int InitialDelay;

    /**
     * Time between repetitions (in seconds)
     * @type int
     */
    var int RepeatDelay;

    /**
     * Target's name (may aswell be a wildcard such as "*")
     * @type string
     */
    var string Target;

    /**
     * Time the message was last shown (Internal counter)
     * @type float
     */
    var float LastDisplayed;
};

/**
 * List of parsed motd messages
 * @type array<sMotdMessage>
 */
var protected array<sMotdMessage> Messages;

/**
 * HTTP client instance
 * @type class'HTTP.Client'
 */
var protected HTTP.Client Client;

/**
 * Indicate whether the mod is enabled
 * @type bool
 */
var config bool Enabled;

/**
 * List of MOTD sources
 * @type array<string>
 */
var config array<string> URL;

/**
 * Max number of messages that will be parsed from a http response
 * Set to 0 for infinity
 * @type int
 */
var config int MaxMessages;

/**
 * Check whether the mod is enabled
 *
 * @return  void
 */
public function PreBeginPlay()
{
    Super.PreBeginPlay();

    if (Level.NetMode == NM_ListenServer || Level.NetMode == NM_DedicatedServer)
    {
        if (Level.Game != None && SwatGameInfo(Level.Game) != None)
        {
            if (self.Enabled && self.URL.Length > 0)
            {
                return;
            }
        }
    }
    self.Destroy();
}

/**
 * Aquire a http client instance and query the MOTD source
 *
 * @return  void
 */
public function BeginPlay()
{
    local int i;

    Super.BeginPlay();

    log("MOTD (version " $ class'Core'.const.VERSION $ ") has been initialized");

    self.Client = Spawn(class'HTTP.Client');
    // Fetch MOTD sources
    for (i = 0; i < self.URL.Length; i++)
    {
        log("Sending a GET request to " $ self.URL[i]);
        self.Client.Send(Spawn(class'Message'), self.URL[i], 'GET', self, 1);
    }

    // Repeat for the whole eternity
    self.SetTimer(class'Core'.const.DELTA, true);
}

/**
 * Go through the list of queued message and attempt display one by one
 */
event Timer()
{
    local int i;
    // Display messages in the order they have been parsed
    for (i = 0; i < self.Messages.Length; i++)
    {
        // The message has not yet been displayed
        if (self.Messages[i].LastDisplayed < 0)
        {
            // but its time hasnt yet come
            if (self.Messages[i].InitialDelay > Level.TimeSeconds)
            {
                continue;
            }
        }
        // This message has already been displayed, but its time hasnt come either
        else if (self.Messages[i].LastDisplayed > Level.TimeSeconds - self.Messages[i].RepeatDelay)
        {
            continue;
        }
        self.DisplayMessage(self.Messages[i].Message, self.Messages[i].Target);
        // Remember the last displayed time
        self.Messages[i].LastDisplayed = Level.TimeSeconds;
    }
    // Handle one-time messages
    for (i = self.Messages.Length-1; i >= 0; i--)
    {
        // The message has already been displayed - remove it from the list
        if (self.Messages[i].RepeatDelay == 0 && self.Messages[i].LastDisplayed >= 0)
        {
            self.Messages.Remove(i, 1);
        }
    }
}

/**
 * Attempt to parse motd messages upon a successful response
 *
 * @see HTTP.ClientOwner.OnRequestSuccess
 */
public function OnRequestSuccess(int StatusCode, string Response, string Hostname, int Port)
{
    local int i;
    local array<string> Blocks, Block, Options;

    if (StatusCode == 200)
    {
        // Ensure unix-style line endings
        Response = class'Utils.StringUtils'.static.Replace(Response, "\r\n", "\n");  // windows
        Response = class'Utils.StringUtils'.static.Replace(Response, "\r", "\n");  // old mac

        Blocks = class'Utils.StringUtils'.static.Part(Response, class'Core'.const.BLOCK_DELIMITER);

        for (i = 0; i < Blocks.Length; i++)
        {
            if (Len(Blocks[i]) > class'Core'.const.MAX_BLOCK_LENGTH)
            {
                log(self $ ": " $ Left(Blocks[i], 20) $ " is too large to be parsed");
                continue;
            }
            // Split message header from the actual message
            Block = class'Utils.StringUtils'.static.Part(Blocks[i], class'Core'.const.HEADER_DELIMITER);

            if (Block.Length >= 2)
            {
                // Parse options
                Options = class'Utils.StringUtils'.static.Part(Block[0], class'Core'.const.OPTION_DELIMITER);
                // Get rid of the parsed header
                Block.Remove(0, 1);
                // Attempt to queue this message
                if (self.QueueMessage(class'Utils.ArrayUtils'.static.Join(Block, class'Core'.const.HEADER_DELIMITER), Options))
                {
                    continue;
                }
            }
            log(self $ ": failed to parse " $ Left(Blocks[i], 20));
        }
    }
    else
    {
        log(self $ ": MOTD source " $ Hostname $ " is not available (" $ StatusCode $ ")");
    }
}

/**
 * Log an error upon a failure
 *
 * @see HTTP.ClientOwner.OnRequestFailure
 */
public function OnRequestFailure(eClientError ErrorCode, string ErrorMessage, string Hostname, int Port)
{
    log(self $ ": MOTD source " $ Hostname $ " is not available (" $ ErrorMessage $ ")");
}

/**
 * Attempt to queue a MOTD message
 * Return whether the operation was successful
 *
 * @param   string Message
 *          MOTD message
 * @param   array<string> Options
 *          List of options
 * @return  bool
 */
protected function bool QueueMessage(string Message, array<string> Options)
{
    local sMotdMessage NewMessage;
    // Check for the message limit
    if (self.MaxMessages > 0 && self.Messages.Length >= self.MaxMessages)
    {
        log(self $ ": reached the message limit of " $ self.MaxMessages);
        return false;
    }
    Message = class'Utils.StringUtils'.static.Strip(Message);
    // The options array should at least contain 2 items (which is initial delay and repetition delay)
    if (Message != "" && Options.Length >= 2)
    {
        if (class'Utils.StringUtils'.static.IsDigit(Options[0]) && class'Utils.StringUtils'.static.IsDigit(Options[1]))
        {
            NewMessage.LastDisplayed = -1;
            NewMessage.InitialDelay = Max(0, int(Options[0]));
            NewMessage.RepeatDelay = Max(0, int(Options[1]));
            NewMessage.Message = Message;
            // Add an optional target
            if (Options.Length > 2)
            {
                NewMessage.Target = class'Utils.StringUtils'.static.Strip(Options[2]);
            }
            self.Messages[self.Messages.Length] = NewMessage;
            return true;
        }
    }
    return false;
}

/**
 * Display a targeted motd message
 *
 * @param   string Message
 * @param   string Target
 * @return  void
 */
protected function DisplayMessage(string Message, string Target)
{
    local int i;
    local array<string> Lines;
    local string Name;
    local PlayerController PC;

    Lines = class'Utils.StringUtils'.static.Part(class'Utils.StringUtils'.static.NormNewline(Message), "\n");

    foreach DynamicActors(class'PlayerController', PC)
    {
        // Make name colourless
        Name = class'Utils.StringUtils'.static.Strip(
            class'Utils.StringUtils'.static.Filter(PC.PlayerReplicationInfo.PlayerName)
        );
        if (Target == "" || class'Utils.StringUtils'.static.Match(Name, Target))
        {
            // Display the message line by line
            for (i = 0; i < Lines.Length; i++)
            {
                class'Utils.LevelUtils'.static.TellPlayer(Level, Lines[i], PC);
            }
        }
    }
}

event Destroyed()
{
    if (self.Client != None)
    {
        self.Client.Destroy();
        self.Client = None;
    }

    log(self $ " is about to be destroyed");

    Super.Destroyed();
}

/* vim: set ft=java: */

class Core extends SwatGame.SwatMutator
 implements HTTP.ClientOwner;

/**
 * Copyright (c) 2014 Sergei Khoroshilov <kh.sergei@gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

import enum eClientError from HTTP.Client;

/**
 * MOTD package version
 * @type string
 */
const VERSION = "1.1.0";

/**
 * Fixed tick rate (seconds)
 * @type float
 */
const DELTA = 0.5;

/**
 * Max message block length
 * @type int
 */
const MAX_BLOCK_LENGTH = 1024;

/**
 * Message block delimiter
 * @type string
 */
const BLOCK_DELIMITER = "\n\n";

/**
 * Header block delimiter
 * @type string
 */
const HEADER_DELIMITER = "\n";

/**
 * Message options delimiter
 * @type string
 */
const OPTION_DELIMITER = "\t";

/**
 * Message Block structure:
 *     Option1 $ OPTION_DELIMITER $ Option2 $ OPTION_DELIMITER $ Option3 $ HEADER_DELIMITER $ Line1\nLine2\n $ BLOCK_DELIMITER
 *
 * Example:
 *     60\t0\t*
 *     Welcome to the server!
 *     Please follow the rules and have fun.
 *
 *     65\t120\t*
 *     Visit us at example.com
 */

struct sMotdMessage
{
    /**
     * MOTD message
     * @type string
     */
    var string Message;

    /**
     * Initial message delay since level startup (in seconds) (Internal counter)
     * @type int
     */
    var int InitialDelay;

    /**
     * Time between repetitions (in seconds)
     * @type int
     */
    var int RepeatDelay;

    /**
     * Target's name (may aswell be a wildcard such as "*")
     * @type string
     */
    var string Target;

    /**
     * Time the message was last shown (Internal counter)
     * @type float
     */
    var float LastDisplayed;
};

/**
 * List of parsed motd messages
 * @type array<sMotdMessage>
 */
var protected array<sMotdMessage> Messages;

/**
 * HTTP client instance
 * @type class'HTTP.Client'
 */
var protected HTTP.Client Client;

/**
 * Indicate whether the mod is enabled
 * @type bool
 */
var config bool Enabled;

/**
 * List of MOTD sources
 * @type array<string>
 */
var config array<string> URL;

/**
 * Max number of messages that will be parsed from a http response
 * Set to 0 for infinity
 * @type int
 */
var config int MaxMessages;

/**
 * Check whether the mod is enabled
 *
 * @return  void
 */
public function PreBeginPlay()
{
    Super.PreBeginPlay();

    if (Level.NetMode == NM_ListenServer || Level.NetMode == NM_DedicatedServer)
    {
        if (Level.Game != None && SwatGameInfo(Level.Game) != None)
        {
            if (self.Enabled && self.URL.Length > 0)
            {
                return;
            }
        }
    }
    self.Destroy();
}

/**
 * Aquire a http client instance and query the MOTD source
 *
 * @return  void
 */
public function BeginPlay()
{
    local int i;

    Super.BeginPlay();

    log("MOTD (version " $ class'Core'.const.VERSION $ ") has been initialized");

    self.Client = Spawn(class'HTTP.Client');
    // Fetch MOTD sources
    for (i = 0; i < self.URL.Length; i++)
    {
        log("Sending a GET request to " $ self.URL[i]);
        self.Client.Send(Spawn(class'Message'), self.URL[i], 'GET', self, 1);
    }

    // Repeat for the whole eternity
    self.SetTimer(class'Core'.const.DELTA, true);
}

/**
 * Go through the list of queued message and attempt display one by one
 */
event Timer()
{
    local int i;
    // Display messages in the order they have been parsed
    for (i = 0; i < self.Messages.Length; i++)
    {
        // The message has not yet been displayed
        if (self.Messages[i].LastDisplayed < 0)
        {
            // but its time hasnt yet come
            if (self.Messages[i].InitialDelay > Level.TimeSeconds)
            {
                continue;
            }
        }
        // This message has already been displayed, but its time hasnt come either
        else if (self.Messages[i].LastDisplayed > Level.TimeSeconds - self.Messages[i].RepeatDelay)
        {
            continue;
        }
        self.DisplayMessage(self.Messages[i].Message, self.Messages[i].Target);
        // Remember the last displayed time
        self.Messages[i].LastDisplayed = Level.TimeSeconds;
    }
    // Handle one-time messages
    for (i = self.Messages.Length-1; i >= 0; i--)
    {
        // The message has already been displayed - remove it from the list
        if (self.Messages[i].RepeatDelay == 0 && self.Messages[i].LastDisplayed >= 0)
        {
            self.Messages.Remove(i, 1);
        }
    }
}

/**
 * Attempt to parse motd messages upon a successful response
 *
 * @see HTTP.ClientOwner.OnRequestSuccess
 */
public function OnRequestSuccess(int StatusCode, string Response, string Hostname, int Port)
{
    local int i;
    local array<string> Blocks, Block, Options;

    if (StatusCode == 200)
    {
        Blocks = class'Utils.StringUtils'.static.Part(Response, class'Core'.const.BLOCK_DELIMITER);

        for (i = 0; i < Blocks.Length; i++)
        {
            if (Len(Blocks[i]) > class'Core'.const.MAX_BLOCK_LENGTH)
            {
                log(self $ ": " $ Left(Blocks[i], 20) $ " is too large to be parsed");
                continue;
            }
            // Split message header from the actual message
            Block = class'Utils.StringUtils'.static.Part(Blocks[i], class'Core'.const.HEADER_DELIMITER);

            if (Block.Length >= 2)
            {
                // Parse options
                Options = class'Utils.StringUtils'.static.Part(Block[0], class'Core'.const.OPTION_DELIMITER);
                // Get rid of the parsed header
                Block.Remove(0, 1);
                // Attempt to queue this message
                if (self.QueueMessage(class'Utils.ArrayUtils'.static.Join(Block, class'Core'.const.HEADER_DELIMITER), Options))
                {
                    continue;
                }
            }
            log(self $ ": failed to parse " $ Left(Blocks[i], 20));
        }
    }
    else
    {
        log(self $ ": MOTD source " $ Hostname $ " is not available (" $ StatusCode $ ")");
    }
}

/**
 * Log an error upon a failure
 *
 * @see HTTP.ClientOwner.OnRequestFailure
 */
public function OnRequestFailure(eClientError ErrorCode, string ErrorMessage, string Hostname, int Port)
{
    log(self $ ": MOTD source " $ Hostname $ " is not available (" $ ErrorMessage $ ")");
}

/**
 * Attempt to queue a MOTD message
 * Return whether the operation was successful
 *
 * @param   string Message
 *          MOTD message
 * @param   array<string> Options
 *          List of options
 * @return  bool
 */
protected function bool QueueMessage(string Message, array<string> Options)
{
    local sMotdMessage NewMessage;
    // Check for the message limit
    if (self.MaxMessages > 0 && self.Messages.Length >= self.MaxMessages)
    {
        log(self $ ": reached the message limit of " $ self.MaxMessages);
        return false;
    }
    Message = class'Utils.StringUtils'.static.Strip(Message);
    // The options array should at least contain 2 items (which is initial delay and repetition delay)
    if (Message != "" && Options.Length >= 2)
    {
        if (class'Utils.StringUtils'.static.IsDigit(Options[0]) && class'Utils.StringUtils'.static.IsDigit(Options[1]))
        {
            NewMessage.LastDisplayed = -1;
            NewMessage.InitialDelay = Max(0, int(Options[0]));
            NewMessage.RepeatDelay = Max(0, int(Options[1]));
            NewMessage.Message = Message;
            // Add an optional target
            if (Options.Length > 2)
            {
                NewMessage.Target = class'Utils.StringUtils'.static.Strip(Options[2]);
            }
            self.Messages[self.Messages.Length] = NewMessage;
            return true;
        }
    }
    return false;
}

/**
 * Display a targeted motd message
 *
 * @param   string Message
 * @param   string Target
 * @return  void
 */
protected function DisplayMessage(string Message, string Target)
{
    local int i;
    local array<string> Lines;
    local string Name;
    local PlayerController PC;

    Lines = class'Utils.StringUtils'.static.Part(class'Utils.StringUtils'.static.NormNewline(Message), "\n");

    foreach DynamicActors(class'PlayerController', PC)
    {
        // Make name colourless
        Name = class'Utils.StringUtils'.static.Strip(
            class'Utils.StringUtils'.static.Filter(PC.PlayerReplicationInfo.PlayerName)
        );
        if (Target == "" || class'Utils.StringUtils'.static.Match(Name, Target))
        {
            // Display the message line by line
            for (i = 0; i < Lines.Length; i++)
            {
                class'Utils.LevelUtils'.static.TellPlayer(Level, Lines[i], PC);
            }
        }
    }
}

event Destroyed()
{
    if (self.Client != None)
    {
        self.Client.Destroy();
        self.Client = None;
    }

    log(self $ " is about to be destroyed");

    Super.Destroyed();
}

/* vim: set ft=java: */