#!
# coding: utf-8
# Copyright (C) 2017 TOPS SYSTEMS
### @file dbgCommentInserter.py
### @brief debug comment inserter
###
### LSTファイル内のデバッグコメントを検出し、
### ISIM-LOGファイル内の対応箇所に挿入する
###
### Contact: izumida@topscom.co.jp
###
### @author: M.Izumida
### @date: November 8, 2017
###
# Original: fltFormatter.py v01r01 April 12
# Written for Python 2.7 (NOT FOR 3.x)
#=======================================================================
# インポート宣言
from __future__ import unicode_literals
import sys
import re
import argparse
import os
import codecs
from datetime import datetime
#=======================================================================
# バージョン文字列
versionSTR = "dbgCommentInserter.py v01r02 Tops Systems (pgm by mpi)"
#=======================================================================
# 共通サブルーチン
#-------------------------------------------------------------------
def errPrint(mes):
"""errPrint.
エラー出力へのメッセージ表示
後の始末はその後で別に書くこと
"""
sys.stderr.write(mes)
sys.stderr.write('\n')
#-------------------------------------------------------------------
def stdExceptionHandler(mes):
"""standard Exception Handler.
エラーメッセージを送出し、デバッグのための情報を出力する
"""
errPrint("Exception Captured: " + str(mes))
errPrint("0:" + str(sys.exc_info()[0]))
errPrint("1:" + str(sys.exc_info()[1]))
errPrint("2:" + str(sys.exc_info()[2]))
#-------------------------------------------------------------------
def tryIntParse(st, dval, radix=10):
"""try Parse string to Integer
文字列stをパースして整数化できれば値を返す、できなければデフォルト値dvalを返す
"""
try:
work = int(st, radix)
except:
return dval
return work
#=======================================================================
# 解析オプション クラス
class Options:
"""Options Class.
グローバルオプションを保持するクラス
"""
pass
#=======================================================================
# LSTファイルリーダクラス
[ドキュメント]class LstFileReader:
"""LstFile Reader Class.
LSTファイルを読みとり、デバッグコメントが付加されていれば
アドレス対コメントの連想配列として確保する。
毎行アドレスを確保したのちデバッグコメントを探す。
デバッグコメントがあればその時点で確保されているアドレスに紐づける
"""
#--------------------------------------------------------------------
def __init__(self, inputFnam):
"""LST File Reader Constructor
コンストラクタ
"""
self.iFname = inputFnam #<<! 入力LSTファイル名
# アドレスの検索表現
self.addrRE = re.compile("^ ([0-9a-fA-F]+) ")
# デバッグコメントの検索表現
self.dbgComRE = re.compile(";\+\+\>(.*)$");
# 連想配列
self.adr2dc = dict()
# 制御
self.readStatus = 0
self.adr = ""
# debug
self.debug = False
self.verbose = False
#--------------------------------------------------------------------
[ドキュメント] def read(self):
"""Read method
LSTファイルを読み込むメソッド。読み込み成功すれば真を返す。
"""
try:
with open(self.iFname, 'r') as f:
for line in f:
self.rLine(line)
except:
stdExceptionHandler("Error: in file reading = " + self.iFname)
return False
return True
#--------------------------------------------------------------------
[ドキュメント] def rLine(self, lin):
"""Read Line method
読み取った1行を処理するメソッド
"""
adrTmp = self.addrRE.match(lin)
if adrTmp:
self.adr = adrTmp
dc = self.dbgComRE.search(lin)
if dc:
self.adr2dc[self.adr.group(1)] = dc.group(1)
if self.verbose:
print "ADR=", self.adr.group(1), " DC=", self.adr2dc[self.adr.group(1)]
return False
#--------------------------------------------------------------------
[ドキュメント] def dumpAdr2Dic(self, fname):
"""Dump Adr 2 Dic
辞書のダンプ
"""
try:
with codecs.open(fname, 'w', 'utf-8-sig') as wf:
for k, v in sorted(self.adr2dc.items()):
wf.write(k + "=" + v + "\n")
except:
stdExceptionHandler("Error: Dump file = " + fname)
return False
return True
#=======================================================================
# LOGファイルリーダライタクラス
[ドキュメント]class LogFileReaderWriter:
"""LOG File Reader/Writer Class.
入力 LOGファイルを読み込み、連想配列が保持するアドレスを発見したならば
デバッグコメントを挿入する。
"""
#--------------------------------------------------------------------
def __init__(self, inam, onam, adrDic, mrk):
"""LOG File Reader/Writer Constructor
コンストラクタ
"""
self.iFname = inam #<<! 入力LOGファイル名
self.oFname = onam #<<! 出力LOGファイル名
self.dic = adrDic #<<! 連想配列
self.markSTR = mrk #<<! マーク文字列
# アドレスの検索表現
self.addrRE = re.compile("FTCH:([0-9a-fA-F]+):")
# debug
self.debug = False
self.verbose = False
#--------------------------------------------------------------------
[ドキュメント] def read(self):
"""Read method
LOGファイルを読み込むメソッド。読み込み成功すれば真を返す。
"""
try:
with codecs.open(self.oFname, 'w', 'utf-8-sig') as wf:
with open(self.iFname, 'r') as f:
for line in f:
wf.write(self.rLine(line))
wf.write('\n')
except:
stdExceptionHandler("Error: file processing = " + self.iFname + ":" + self.oFname)
return False
return True
#--------------------------------------------------------------------
[ドキュメント] def rLine(self, lin):
"""Read Line method
読み取った1行を処理するメソッド
"""
adrList = self.addrRE.findall(lin)
linbody = lin.rstrip('\r\n')
for adr in adrList:
adrU = adr.upper()
if adrU in self.dic:
if self.verbose:
print "FIND DC ADR=", adrU
return linbody + self.markSTR + self.dic[adrU]
return linbody
#=======================================================================
# メインプログラム
def main():
"""main.
メインプログラム
"""
#-----------------------------------------------------------------------
# コマンドラインオプション処理
#
parser = argparse.ArgumentParser(description='dbgCommentInserter, ISIM-LOG-debug helper.')
parser.add_argument('--ILOG', nargs=1, help='Input LOG file name.')
parser.add_argument('--OLOG', nargs=1, help='Output LOG file name.')
parser.add_argument('--LST', nargs=1, help='LST file name.')
parser.add_argument('--MARK', nargs=1, help='COMMENT marker string.')
parser.add_argument('-d', dest='debug', help='Debug mode, print debug information.', action='store_true', default=False)
parser.add_argument('-v', dest='verbose', help='Verbose mode.', action='store_true', default=False)
parser.add_argument('-V', dest='VERSION', help='Show Version, then exit', action='store_true', default=False)
args = parser.parse_args()
#-----------------------------------------------------------------------
# Version 表示
#
print versionSTR
if args.VERSION:
sys.exit(0)
#-----------------------------------------------------------------------
# ファイル名処理
#
if args.LST is None:
errPrint('ERROR: NO LST file!')
sys.exit(1)
else:
lstFname = args.LST[0]
if not os.path.isfile(lstFname):
errPrint('ERROR: LST file, NOT EXIST. ?=' + lstFname)
sys.exit(1)
if args.ILOG is None:
errPrint('ERROR: NO INPUT LOG file!')
sys.exit(1)
else:
ilogFname = args.ILOG[0]
if not os.path.isfile(ilogFname):
errPrint('ERROR: INPUT LOG file, NOT EXIST. ?=' + ilogFname)
sys.exit(1)
if args.OLOG is None:
ologFname = "dbgCom.LOG"
else:
ologFname = args.OLOG[0]
if args.MARK is None:
markSTR = "●"
else:
markSTR = args.MARK[0]
#-----------------------------------------------------------------------
# パラメータ処理
#-----------------------------------------------------------------------
# 実処理
#
print "-"*50
#LSTファイルを読み込み
lst = LstFileReader(lstFname)
lst.debug = args.debug
lst.verbose = args.verbose
if not lst.read():
sys.exit(1)
#lst.dumpAdr2Dic("adr2dic.txt")
#INPUT LOGファイルを読み込み
log = LogFileReaderWriter(ilogFname, ologFname, lst.adr2dc, markSTR)
log.debug = args.debug
log.verbose = args.verbose
if not log.read():
sys.exit(1)
today = datetime.today()
print today.strftime("FINISH: %Y/%m/%d %H:%M:%S")
#-----------------------------------------------------------------------
# 正常終了
#
sys.exit(0)
#=======================================================================
# メインプログラムの起動
if __name__ == "__main__":
main()