2016年06月19日
自動埋め込みツール公開
EXCEL 2007 VBAで、デバッグ用の関数をソースファイル(inoファイル)に埋め込むツールを作りましたので公開します。(EXCELでVBAを開き、UserFormに他のコントロールを配置して各イベントにコピペしてください。)
但し欠点が2つあります。
1.改行コードがLF→CRLFになる。→TeraPadで改行コードをCRLF→LF変更できます。
2.日本語が化けます。日本語の処理は、Arduino IDE上でやりましょう。
上記欠点を分かった上でお試しください。
ツールの本体は、UserFormに書きました。<選択>を押すとファイル選択のダイアログが開くのでinoファイルを選んでください。ファイルを開いたら、<挿入する>を押してください。そうすると保存するファイル名を聞かれるので適当な名前をつけてください。
debugPrint, debugRegPrint, breakPointの3つの関数呼び出しを、ターゲットのソースコードの関数定義の先頭行にコメント文として追加します。コメント文とした理由はターゲットのRAMに余裕がないかもしれないので、適宜コメントを外す方が実践的かなあと思ったからです。またdebugPrintは関数名を表示させるものなので引数の文字列に関数名を自動的に入れるようにしました。
デザイン
以下、ソースコードです。
debugPrintに渡す関数名は以下のように探すことにしました。
C言語の関数名は、'{' の前か前行にあります。ですがここでは'}'のある行かその前行だと決め打ちして作っています。ですのでうまくヒットしない場合もあります。また配列やif文、while文、for文、switch文は関数名ではないので除外します。まだ除外し忘れているものがあるかもしれません。
VBAから上記を直接実行させてもよいのですが、シートを開いたときにすぐに実行できるように、ボタンにUserFormをオープンするプロシージャを書いただけです。下記はお好みで決めてください。
デザイン
但し欠点が2つあります。
1.改行コードがLF→CRLFになる。→TeraPadで改行コードをCRLF→LF変更できます。
2.日本語が化けます。日本語の処理は、Arduino IDE上でやりましょう。
上記欠点を分かった上でお試しください。
ツールの本体は、UserFormに書きました。<選択>を押すとファイル選択のダイアログが開くのでinoファイルを選んでください。ファイルを開いたら、<挿入する>を押してください。そうすると保存するファイル名を聞かれるので適当な名前をつけてください。
debugPrint, debugRegPrint, breakPointの3つの関数呼び出しを、ターゲットのソースコードの関数定義の先頭行にコメント文として追加します。コメント文とした理由はターゲットのRAMに余裕がないかもしれないので、適宜コメントを外す方が実践的かなあと思ったからです。またdebugPrintは関数名を表示させるものなので引数の文字列に関数名を自動的に入れるようにしました。
デザイン
以下、ソースコードです。
debugPrintに渡す関数名は以下のように探すことにしました。
C言語の関数名は、'{' の前か前行にあります。ですがここでは'}'のある行かその前行だと決め打ちして作っています。ですのでうまくヒットしない場合もあります。また配列やif文、while文、for文、switch文は関数名ではないので除外します。まだ除外し忘れているものがあるかもしれません。
Option Explicit
Private Sub btnDeleteBreakPoint_Click()
End Sub
Private Sub btnGetFilePath_Click()
'参照ボタンがクリックされた
Dim fType, prompt As String
Dim fPath As Variant
Dim ws As Worksheet
Set ws = Worksheets("Sheet1")
'ダイアログのタイトルを指定
prompt = "inoファイルを選択して下さい"
'ファイル参照ダイアログの表示
fPath = Application.GetOpenFilename(fType, , prompt)
If fPath = False Then
'ダイアログでキャンセルボタンが押された場合は処理を終了します
End
End If
'TextBox1にファイル名をセット
TextBox1.Text = fPath
End Sub
Private Sub btnAddDebugPoint_Click()
'debugPrint(), debugRegPrint(),breakPoint()を追加する
'ファイルを開く
Dim strBuf As String
Dim strArray() As String
Dim pos As Integer
Dim i As Long
Open TextBox1.Text For Input As #1
Line Input #1, strBuf
'strBuf末尾にCRが含まれているかどうか判定
pos = 1
pos = InStr(pos, strBuf, vbLf)
If pos = 0 Then
'改行コードがCRLFの場合(切り出したstringには改行コードは含まれない為)
ReDim Preserve strArray(0) '既に1行読み込んでいる為
strArray(0) = strBuf
i = 1
Do Until EOF(1)
Line Input #1, strBuf ' ファイルから一行読み込み
ReDim Preserve strArray(i) ' 配列長を変更
strArray(i) = strBuf ' 配列の最終要素に読み込んだ値を代入
i = i + 1 ' 配列の要素数を加算
Loop
Else
'改行コードがLFの場合(VBAはLFを改行と見做さないのでinoファイル全体が1つの文字列になる)
Dim tmp As Variant 'LFコードでsplitして格納
tmp = Split(strBuf, vbLf) 'strBufをLFコードで区切りtmpに格納
ReDim Preserve strArray(UBound(tmp))
i = 0
For i = 0 To UBound(tmp)
strArray(i) = tmp(i)
Next i
End If
Close #1
Dim j As Long
Dim funcName As String
'strArray()の解析(関数名を取り出してdebugPrint文を追加)
For i = 0 To 20000
''{'を含む行を見つける
pos = InStr(1, strArray(i), "{")
If pos = 0 Then
'何もしない
ElseIf pos >= 1 Then
funcName = ""
If checkString(strArray, i, funcName) = True Then
'関数名の個所なのでdebugXXX()を挿入する
'次の行からdebugXXX文を3行追加し、新strArray配列を作る
ReDim Preserve strArray(UBound(strArray) + 3) '配列要素を+3する
For j = UBound(strArray) To i + 3 Step -1
strArray(j) = strArray(j - 3)
Next j
strArray(i + 1) = "/***********/ //debugPrint(""" & funcName & """);"
strArray(i + 2) = "/* DEBUG */ //debugRegPrint(""*"",);"
strArray(i + 3) = "/***********/ //breakPoint();"
i = i + 4
Else
'関数名の個所ではなかったので何もしない
End If
End If
If i = UBound(strArray) Then
Exit For
End If
Next i
'新しくファイルを作成する
Open Application.GetSaveAsFilename(TextBox1.Text) For Output As #1
For i = 0 To UBound(strArray)
Print #1, strArray(i)
Next i
Close #1
End Sub
Private Function checkString(strArray() As String, strPointer As Long, funcName As String) As Boolean
'関数名の個所かどうか判定する 関数名ならTrueを返す
Dim pos As Integer
Dim nameFlag As Boolean
nameFlag = True
pos = InStr(1, LTrim(strArray(strPointer)), "{")
If pos = 1 Then
Call getName(Trim(strArray(strPointer - 1)), funcName, nameFlag)
ElseIf pos > 1 Then
Call getName(Trim(strArray(strPointer)), funcName, nameFlag)
End If
checkString = nameFlag
End Function
Private Sub getName(funcString As String, funcName As String, nameFlag As Boolean)
If InStr(1, funcString, "=") = 0 And InStr(1, funcString, "(") > 2 And InStr(1, funcString, "if") = 0 _
And InStr(1, funcString, "switch") = 0 And InStr(1, funcString, "while") = 0 _
And InStr(1, funcString, "for ") = 0 And InStr(1, funcString, "for(") = 0 Then
'関数名である
Dim tmp As Variant
If InStr(1, funcString, "//") > 0 Then
tmp = Split(funcString, "//")
funcString = Trim(tmp(0))
End If
If InStr(1, funcString, "{") = 0 Then
funcName = funcString
Else
tmp = Split(funcString, "{")
funcName = Trim(tmp(0))
End If
nameFlag = True
Else
'配列名である(または関数の引数だけの行もかな?)
nameFlag = False
End If
End Sub
Private Sub btnDeleteDebugPoint_Click()
'debugPrint(), debugRegPrint(),breakPoint()を削除する
End Sub
Private Sub TextBox1_Change()
End Sub
Private Sub UserForm_Click()
' UserForm1.Show (vbModeless)
End Sub
VBAから上記を直接実行させてもよいのですが、シートを開いたときにすぐに実行できるように、ボタンにUserFormをオープンするプロシージャを書いただけです。下記はお好みで決めてください。
デザイン
Sub Macro1()
'
' Macro1 Macro
' Arduino IDEのソースコードにデバッグ用のコードを挿入するマクロ。
'
'
UserForm1.Show (vbModeless)
End Sub
【このカテゴリーの最新記事】
-
no image
-
no image
-
no image
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/5166189
※ブログオーナーが承認したトラックバックのみ表示されます。
※言及リンクのないトラックバックは受信されません。
この記事へのトラックバック