ソースコードにスクリプトを埋め込んで、ソースコードを生成させる
はじめに
わりと一発ネタ。大したことやってません。仕事で必要に感じたので作ってみました。せっかくなのでここでも紹介。
タイトルをもっと適切なものに書き換えたい。
背景
諸々の事情から、部分的に冗長なコードを書かないといけない時があると思います。
そんなときは、コードを生成するスクリプトを書くのが一般的な対応法かと思います。
例えばこんな感じに。(もうちょっと現実にありえそうな例を出したかったのですが……)
% cat hoge.cpp void hogehoge( ) { /* ここに冗長なコードを書きたい */ } ... snip ... % cat hoge.py #!/usr/bin/python for num in range( 20 ): print ' hoge%02d = fuga[%d] ;' % ( num, num ) % ./hoge.py hoge00 = fuga[0] ; hoge01 = fuga[1] ; hoge02 = fuga[2] ; ... snip ... hoge19 = fuga[19] ;
解決案
じゃあhoge.cppの中にhoge.pyが埋め込めればいいんじゃね? って考えてこんなpythonコードを書いてみました。
#!/usr/bin/python """ embedded_procedure.py this script enables us to embed some script into your source code. """ import sys import optparse import re import commands if __name__ == '__main__': usage = "%prog [options] [filename]" parser = optparse.OptionParser( usage=usage ) parser.parse_args( ) if len( sys.argv ) == 1: stream = sys.stdin elif len( sys.argv ) == 2: stream = open( sys.argv[ 1 ], 'r' ) else: parser.print_help( ) exit( ) command_file = '.tmp.command' command = '' re_begin = re.compile( r'^\s*/\*\*\*\*\s*([^\s]+)' ) re_head = re.compile( r'^\s*\*\s' ) re_end = re.compile( r'^\s*\*/' ) match = False buffer = '' for line in stream: m = re_begin.match( line ) if m: match = True command = m.group( 1 ) elif match and re_end.match( line ): match = False fp = open( command_file, 'w' ) fp.write( buffer ) fp.close( ) print commands.getoutput( '%s %s' % ( command, command_file ) ) commands.getoutput( 'rm -f %s' % command_file ) buffer = '' elif match: buffer += re_head.sub( '', line ) else: print line,
これを使うと、先の例はこんな感じに書き換えられます。
% cat hoge.cpp void hogehoge( ) { /**** python * for num in range( 20 ): * print ' hoge%02d = fuga[%d] ;' % ( num, num ) */ } ... snip ... % ./embedded_procedure.py hoge.cpp void hogehoge( ) { hoge00 = fuga[0] ; hoge01 = fuga[1] ; hoge02 = fuga[2] ; ... snip ... hoge19 = fuga[19] ; } ... snip ...
これで、hoge.cppのみを管理すればよくなりました。