source: azure_iot_hub/trunk/asp3_dcre/utils/gentest.rb@ 388

Last change on this file since 388 was 388, checked in by coas-nagasima, 5 years ago

Azure IoT Hub Device C SDK を使ったサンプルの追加

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-ruby
File size: 13.0 KB
Line 
1#!/usr/bin/env ruby
2# -*- coding: utf-8 -*-
3#
4# TOPPERS Software
5# Toyohashi Open Platform for Embedded Real-Time Systems
6#
7# Copyright (C) 2007-2016 by Embedded and Real-Time Systems Laboratory
8# Graduate School of Information Science, Nagoya Univ., JAPAN
9#
10# 上記著作権者
11は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
12# ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13# 変・再é…
14å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
15# (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
16# 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17# スコード中に含まれていること.
18# (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
19# 用できる形で再é…
20å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
21å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
22# 者
23マニュアルなど)に,上記の著作権表示,この利用条件および下記
24# の無保証規定を掲載すること.
25# (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
26# 用できない形で再é…
27å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
28# と.
29# (a) 再é…
30å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
31マニュアルなど)に,上記の著
32# 作権表示,この利用条件および下記の無保証規定を掲載すること.
33# (b) 再é…
34å¸ƒã®å½¢æ…
35‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
36# 報告すること.
37# (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
38# 害からも,上記著作権者
39およびTOPPERSプロジェクトをå…
40è²¬ã™ã‚‹ã“と.
41# また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
42# 由に基づく請求からも,上記著作権者
43およびTOPPERSプロジェクトを
44# å…
45è²¬ã™ã‚‹ã“と.
46#
47# 本ソフトウェアは,無保証で提供されているものである.上記著作権者
48お
49# よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
50# に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
51# アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
52# の責任を負わない.
53#
54# $Id$
55#
56
57#
58# テストプログラム生成ツール
59#
60
61#
62# 生成動作を決めるための設定
63#
64$parameterDefinition = {
65 "get_tst" => { 2 => "STAT" },
66 "get_pri" => { 2 => "PRI" },
67 "get_inf" => { 1 => "intptr_t" },
68 "ref_tsk" => { 2 => "T_RTSK" },
69 "ref_sem" => { 2 => "T_RSEM" },
70 "wai_flg" => { 4 => "FLGPTN" },
71 "pol_flg" => { 4 => "FLGPTN" },
72 "twai_flg" => { 4 => "FLGPTN" },
73 "ref_flg" => { 2 => "T_RFLG" },
74 "rcv_dtq" => { 2 => "intptr_t" },
75 "prcv_dtq" => { 2 => "intptr_t" },
76 "trcv_dtq" => { 2 => "intptr_t" },
77 "ref_dtq" => { 2 => "T_RDTQ" },
78 "rcv_pdq" => { 2 => "intptr_t" , 3 => "PRI" },
79 "prcv_pdq" => { 2 => "intptr_t" , 3 => "PRI" },
80 "trcv_pdq" => { 2 => "intptr_t" , 3 => "PRI" },
81 "ref_pdq" => { 2 => "T_RPDQ" },
82 "ref_mtx" => { 2 => "T_RMTX" },
83 "ref_mbf" => { 2 => "T_RMBF" },
84 "get_mpf" => { 2 => "void *" },
85 "pget_mpf" => { 2 => "void *" },
86 "tget_mpf" => { 2 => "void *" },
87 "ref_mpf" => { 2 => "T_RMPF" },
88 "get_tim" => { 1 => "SYSTIM" },
89 "ref_cyc" => { 2 => "T_RCYC" },
90 "ref_alm" => { 2 => "T_RALM" },
91 "ref_ovr" => { 2 => "T_ROVR" },
92 "get_tid" => { 1 => "ID" },
93 "get_did" => { 1 => "ID" },
94 "get_lod" => { 2 => "uint_t" },
95 "mget_lod" => { 3 => "uint_t" },
96 "get_nth" => { 3 => "ID" },
97 "mget_nth" => { 4 => "ID" },
98 "get_ipm" => { 1 => "PRI" },
99 "get_som" => { 1 => "ID" }
100}
101
102$functionParameters = {
103 "target_hrt_set_event" => "HRTCNT hrtcnt"
104}
105
106$functionValue = {
107 "target_hrt_get_current" => "HRTCNT"
108}
109
110$functionReturn = {
111 "target_hrt_get_current" => "0U"
112}
113
114$functionCheckParameter = {
115 "target_hrt_set_event" => "hrtcnt"
116}
117
118#
119# 処理単位のコードを格納するクラス
120#
121class PUCode
122 # 初期化
123 def initialize(puName)
124 @puName = puName # 処理単位の名前
125 @currentCount = "" # 処理カウント
126 @countFlag = false # 処理カウントが使われたか
127 @code = Hash.new { |h,k| h[k] = [] } # 処理単位のコード
128 @variableList = {} # 処理単位の変数
129 @silFlag = false # SILが使われたか
130
131 # 処理カウント変数名の生成
132 case puName
133 when /^TASK([0-9]*)$/
134 @count_var = "task#{$1}_count"
135 when /^CYC([0-9]*)$/
136 @count_var = "cyclic#{$1}_count"
137 when /^ALM([0-9]*)$/
138 @count_var = "alarm#{$1}_count"
139 when /^OVR$/
140 @count_var = "overrun_count"
141 when /^ISR([0-9]*)$/
142 @count_var = "isr#{$1}_count"
143 when /^INTHDR([0-9]*)$/
144 @count_var = "inthdr#{$1}_count"
145 when /^CPUEXC([0-9]*)$/
146 @count_var = "cpuexc#{$1}_count"
147 when /^EXTSVC([0-9]*)$/
148 @count_var = "extsvc#{$1}_count"
149 else
150 @count_var = puName + "_count"
151 end
152 end
153
154 # 処理カウントの設定
155 def setCount(count)
156 @countFlag = true if count != ""
157 @currentCount = count
158 end
159
160 # 処理カウントのインクリメント
161 def incrementCount
162 if @currentCount != ""
163 @currentCount = (@currentCount.to_i + 1).to_s
164 end
165 end
166
167 # コードの追加
168 def append(*lines)
169 lines.each do |line|
170 @code[@currentCount].push(line)
171 end
172 end
173
174 # 変数の追加
175 def addVariable(varName, typeName)
176 @variableList[varName] = typeName
177 end
178
179 # SILの使用
180 def useSil
181 @silFlag = true
182 end
183
184 # 処理単位のコードの出力
185 def generateCode
186 # 不要な処理単位の判定
187 return if @code.length == 0
188
189 # 処理カウント変数の生成
190 if @countFlag
191 print("\nstatic uint_t\t#{@count_var} = 0;\n")
192 end
193
194 # 関数ヘッダの生成
195 case @puName
196 when /^TASK([0-9]*)$/
197 print("\nvoid\n")
198 print("task#{$1}(intptr_t exinf)\n")
199 when /^CYC([0-9]*)$/
200 print("\nvoid\n")
201 print("cyclic#{$1}_handler(intptr_t exinf)\n")
202 when /^ALM([0-9]*)$/
203 print("\nvoid\n")
204 print("alarm#{$1}_handler(intptr_t exinf)\n")
205 when /^OVR$/
206 print("\nvoid\n")
207 print("overrun_handler(ID tskid, intptr_t exinf)\n")
208 when /^ISR([0-9]*)$/
209 print("\nvoid\n")
210 print("isr#{$1}(intptr_t exinf)\n")
211 when /^INTHDR([0-9]*)$/
212 print("\nvoid\n")
213 print("inthdr#{$1}_handler(void)\n")
214 when /^CPUEXC([0-9]*)$/
215 print("\nvoid\n")
216 print("cpuexc#{$1}_handler(void *p_excinf)\n")
217 when /^EXTSVC([0-9]*)$/
218 print("\nER_UINT\n")
219 print("extsvc#{$1}_routine")
220 print("(intptr_t par1, intptr_t par2, intptr_t par3,\n")
221 print("\t\t\t\t\t\t\t\tintptr_t par4, intptr_t par5, ID cdmid)\n")
222 else
223 if $functionValue[@puName]
224 print("\n#{$functionValue[@puName]}\n")
225 else
226 print("\nvoid\n")
227 end
228 print(@puName)
229 if $functionParameters[@puName]
230 print("(#{$functionParameters[@puName]})\n")
231 else
232 print("(void)\n")
233 end
234 end
235
236 print("{\n")
237
238 @variableList.each do |varName, varType|
239 if /^(.+)\w*\*$/ =~ varType
240 varBaseType = $1
241 print("\t#{varBaseType}")
242 print(varBaseType.length < 4 ? "\t\t*" : "\t*")
243 else
244 print("\t#{varType}")
245 print(varType.length < 4 ? "\t\t" : "\t")
246 end
247 print("#{varName};\n")
248 end
249 if @silFlag
250 print("\tSIL_PRE_LOC;\n")
251 end
252 print("\n")
253
254 if @countFlag
255 print("\tswitch (++#{@count_var}) {\n")
256 @code.keys.sort_by { |c| c.to_i }.each do |count|
257 print("\tcase #{count}:\n")
258 @code[count].each do |line|
259 print("\t",line) if line != ""
260 print("\n")
261 end
262 print("\t\tcheck_point(0);\n\n")
263 end
264 print("\tdefault:\n")
265 print("\t\tcheck_point(0);\n")
266 print("\t}\n")
267 else
268 @code[""].each do |line|
269 print(line,"\n")
270 end
271 end
272
273 print("\tcheck_point(0);\n")
274 if /^EXTSVC([0-9]*)$/ =~ @puName
275 print("\treturn(E_SYS);\n")
276 elsif $functionReturn[@pu_nama]
277 print("\treturn(#{$functionReturn[@puName]});\n")
278 end
279 print("}\n")
280 end
281end
282
283#
284# サービスコール呼び出しの読み込み
285#
286def genServiceCall(pu, svc_call, error_code)
287 pu.addVariable("ercd", "ER_UINT")
288 pu.append("\tercd = #{svc_call};")
289
290 if /^([a-z_]+)\((.*)\)$/ =~ svc_call
291 svcName = $1;
292 params = $2.split(/\s*,\s*/)
293
294 if $parameterDefinition.has_key?(svcName)
295 $parameterDefinition[svcName].each do |pos, type|
296 if params.size >= pos
297 varName = params[pos - 1].sub(/^\&/, "")
298 pu.addVariable(varName, type)
299 end
300 end
301 end
302 end
303
304 if !error_code
305 # E_OKが返る場合
306 pu.append("\tcheck_ercd(ercd, E_OK);", "")
307 elsif error_code == "noreturn"
308 # リターンしない場合
309 pu.append("")
310 else
311 pu.append("\tcheck_ercd(ercd, #{error_code});", "")
312 end
313end
314
315#
316# テスト開始コードの生成
317#
318def testStartCode(pu)
319 # テスト開始コードは一度のみ出力する
320 if $startFlag == 0
321 pu.append("\ttest_start(__FILE__);", "")
322 $startFlag = 1
323 end
324end
325
326#
327# ターゲット依存部関数の振る舞いの読み込み
328#
329def targetFunction(line, checkNum)
330 if /^([a-zA-Z_]+)\s*(.*)$/ =~ line
331 functionName = $1
332 line = $2
333 if (pu = $puList[functionName]).nil?
334 # 新しい処理単位の生成
335 pu = $puList[functionName] = PUCode.new(functionName)
336 pu.setCount("1")
337 testStartCode(pu)
338 end
339 end
340
341 if /\-\>\s*([^\s]+)\s*(.*)$/ =~ line
342 retval = $1
343 line = $2
344 end
345 if /\<\-\s*([^\s]+)\s*(.*)$/ =~ line
346 param = $1
347 line = $2
348 end
349
350 pu.append("\tcheck_point(#{checkNum});");
351 if param && $functionCheckParameter[functionName]
352 pu.append(sprintf("\tcheck_assert(%s == %s);",
353 $functionCheckParameter[functionName], param), "")
354 end
355 if retval
356 pu.append("\treturn(#{retval});", "")
357 else
358 pu.append("\treturn;", "")
359 end
360 pu.incrementCount()
361end
362
363#
364# テストスクリプトの読み込み
365#
366def parseLine(line)
367 if /^==\s*(([a-zA-Z_]+)[0-9]*)(.*)$/ =~ line
368 # 処理単位の開始
369 $procFlag = 1
370 puName = $1
371 line2 = $3
372 if (pu = $puList[puName]).nil?
373 # 新しい処理単位の生成
374 pu = $puList[puName] = PUCode.new(puName)
375 end
376 $currentPu = pu
377
378 case line2
379 when /^\-([0-9]+)(.*)$/
380 pu.setCount($1)
381 when /^\-[nN](.*)$/
382 # do nothing.
383 else
384 pu.setCount("")
385 end
386 testStartCode(pu) if /^START/ !~ puName
387 elsif $procFlag != 0
388 pu = $currentPu
389 if /^([0-9]+\:)\s*(.*)$/ =~ line
390 # チェックポイント番号の処理
391 originalCheckNum = $1
392 line = $2
393 checkNum = ($lastCheckPoint += 1).to_s
394 $outputLine.sub!(/#{originalCheckNum}/, "#{checkNum}:")
395
396 case line
397 when /^END$/
398 pu.append("\tcheck_finish(#{checkNum});")
399 $procFlag = 0
400 return
401 when /^HOOK\((.*)\)$/
402 pu.append(sprintf("\t#{$1};", checkNum))
403 return
404 when /^\[(.*)\]$/
405 targetFunction($1, checkNum)
406 return
407 else
408 pu.append("\tcheck_point(#{checkNum});")
409 end
410 end
411
412 case line
413 when /^((assert|state|ipm)\(.*\))$/
414 pu.append("\tcheck_#{$1};", "")
415 when /^(call|DO)\((.*)\)$/
416 call_string = $2
417 pu.append("\t#{call_string};", "")
418 pu.useSil() if /^SIL_..._INT\(\)$/ =~ call_string
419 when /^RETURN((\(.*\))?)$/
420 pu.append("\treturn#{$1};", "")
421 pu.incrementCount()
422 when /^GOTO\((.*)\)$/
423 pu.append("\tgoto #{$1};", "")
424 when /^LABEL\((.*)\)$/
425 pu.append("#{$1}:", "")
426 when /^([a-z_]+\(.*\))\s*(\-\>\s*([A-Za-z0-9_]*))?\s*$/
427 genServiceCall(pu, $1, $3)
428 else
429 warn("Error: #{line}")
430 end
431 end
432end
433
434#
435# エラーチェック
436#
437if ARGV.length < 1
438 abort("Usage: ruby gentest.rb <test_program>")
439end
440
441#
442# 初期化
443#
444inFileName = ARGV.shift
445
446#
447# スクリプトファイル読み込み処理
448#
449$lastCheckPoint = 0 # 最後のチェックポイント番号
450$procFlag = 0 # スクリプト処理中フラグ
451$startFlag = 0 # テスト開始コードの出力フラグ
452$currentPu = nil # 読み込み中の処理単位
453$puList = {} # 処理単位のリスト
454
455begin
456 inFile = File.open(inFileName)
457rescue Errno::ENOENT, Errno::EACCES => ex
458 abort(ex.message)
459end
460
461while line = inFile.gets do
462 $outputLine = line.dup
463 line.chomp!
464 line.sub!(/^\s*\*\s*/, "")
465 line.sub!(/\s*\/\/.*$/, "")
466 line.sub!(/\s*\.\.\..*$/, "")
467
468 while line.sub!(/\\$/, "") do
469 line1 = inFile.gets
470 $outputLine += line1.dup
471 line1.chomp!
472 line1.sub!(/^\s*\*\s*/, "")
473 line1.sub!(/\s*\/\/.*$/, "")
474 line1.sub!(/\s*\.\.\..*$/, "")
475 line += line1
476 end
477 parseLine(line) if line != ""
478 print($outputLine)
479 break if /DO NOT DELETE THIS LINE/ =~ $outputLine
480end
481
482#
483# テストプログラム出力処理
484#
485$puList.keys.sort.each do |puName|
486 $puList[puName].generateCode()
487end
Note: See TracBrowser for help on using the repository browser.