2012/01/04

「今度ね…」

子供を育てていると、ついつい「今度ね」とか「後でね」とか言ってしまう。
大人にとってはその場しのぎで、次の瞬間には忘れてしまう様な事でも、 子供は「今度」や「後で」を楽しみに心待ちにしている事が多い。
そして結局「今度」や「後で」が来ない事を知ると落胆してしまう。
約束を守って貰えない親だと子供に思わせれるのは親として情けないと思うし、 約束を守って貰えない親だと思うしかない子供は不憫だと思う。

だから、自分の子供に「今度」や「後で」の約束をしたら、 必ずこちらから「今度」や「後で」を実現させてあげる様にしようと思うし、 なるべく「○○できたら」とか「○○の後で」と条件を明確にする様にしている。

極論かもしれないが、そういう細かな不信感の積み重ねで 大人になった時に約束は守らなくても良いと思う様な 責任感が希薄な人に育っていくのだとさえ思う。

だから軽々しい口約束は極力控えて約束したらちゃんと守るようにしないとと思う。

2012/01/01

A Happy New Year

新年
  明けまして
    おめでとう
      ございます

今年もよろしくお願いします。

2011/12/14

cvs や svn のリビジョン番号

プログラムを作成する際、 特にまだ未完成で頻繁に修正とコンパイルを繰り返している間は、 どのリビジョンのプログラムを実行しているのか知りたい事はよく有る。
そんな時に、例えば実行時オプションとして -v を指定すると cvs や svn のリビジョン番号とコミットした日時が表示されると便利だ。
しかし、多くの場合において -v オプションを解析し実行するだろう main 関数が含まれるファイルが最終修正されているとは限らない。 従って main 関数の含まれるファイル中に

static	char	*id = "$Id$";
	
などと定義しておいて commit 時に $Id$ を展開したとしても、 必ずしも最新のリビジョンにはならない場合が多い。

そこで -v オプションのハンドラ部分では

static	char	*id = "revision: " REVISION ", " COMMITED ;
	
と記述としておいて make 時に自動で REVISIONCOMMITED を全てのソース/ヘッダファイル中の cvs や svn の $Id$ キーワードから取得して設定する方法を検討してみる。

build 時に必ず実行する必要がある処理なので Makefile に記述して、 make 中で自動的に実行してしまうのが楽。

    :
# 変数定義
PROGRAM  = myprog
OBJECTS  = sub.o pthread.o common.o util.o
HEADER   = myprog.h const.h config.h
 
# 全ソース/ヘッダ中の `$Id' 行から最大のリビジョンを取得する
REVISION = $(shell awk '/\$$Id/{ if($$4 ~ /[[:digit:]]/) \
            if(max < $$4) max = $$4 } END{ print max }' \
            $(OBJECT:.o=.c) $(HEADER) $(PROGRAM).c)
# 全ソース/ヘッダ中の `$Id' 行から最大のリビジョンのコミット日時を取得する
COMMITED = $(shell awk '/\$$Id.*'$(REVISION)'/{ \
            print $$5 " " $$6; exit }' \
            $(OBJECT:.o=.c) $(HEADER) $(PROGRAM).c)
# コンパイルオプション(REVISIONとCOMMITEDを定義)
CFLAGS   = -g -Wall -Wextra -Werror -Wno-unused-parameter -I.-O2 \
            -DREVISION=\""$(REVISION)"\" -DCOMMITED=\""$(COMMITED)"\"
    :
    :
# ターゲット(デフォルトターゲットは touch と $(PROGRAM)に依存
all: touch $(PROGRAM)

# $(PROGRAM).o ファイルの削除($(PROGRAM).o ファイルは必ずコンパイルする)
touch:
    rm $(@).o

$(PROGRAM): $(OBJECTS)
    $(CC) $(CFLAGS) -o $(@) $^ 

$(OBJECTS): $(HEADER)
    :
	
これでどのファイルを commit した場合でも 必ず最新のリビジョンとコミット日付が -v で表示される。

当初ターゲット touchtouch $(PROGRAM).c としていたが、 とある方よりの指摘で rm $(PROGRAM).o に変更した。
ご指摘感謝です > N.S. さま

2011/11/26

shell での while ループにおける問題

シェルスクリプトでコマンドの出力をループ処理する場合は パイプ | を使用するのが一般的な手法だと思うが、 パイプ | を使うとループが別なプロセスとして実行されるので ループ内部で設定したシェル変数がループ外部で参照できないという問題があり、 (存在するとすれば) shell script 業界では割と FAQ 的な問題だ。
何が問題かと言って posix で定義されていないから シェルの実装に依存しているのが一番の問題だったりするのだろう。
この問題に対しては、シェルビルトインの exec (1) を利用して ディスクリプタを複製して while ループの入力を標準入力にしてしまうのが 一番汎用的で柔軟性のある対応だと思うのだが、 シェルを愛する面々は 皆同じ様な苦労をしているのだ と改めて認識した。

当初は一時ファイルを作成する方法を考えついたのだが、 自分的にはなるべく一時ファイルを使いたくなかったので ファイルから入力する部分をバッククォートによるコマンド実行に置き換え等、 色々と試行錯誤した結果ヒアドキュメントを使う方法に落ち着いた。

# これでは正常に動作しなかった
exec 3<&0  0<`${command}`

while read line
    :
	

勿論一時ファイルを作成しても良いのだが、 ヒアドキュメントを利用する事で一時ファイルが不要になる分だけ 処理的に美しいかなと思う (完全に好みの問題)。
  1#!/bin/sh
  2# コマンドの出力をバッククォートしてヒアドキュメントとして使用する
  3
  4command="/path/to/command"
  5count=0
  6
  7# exec 3<&0: 標準入力 (FD0) を FD3 に複製
  8# exec 0<<EOF: ヒアドキュメントを標準入力として使用
  9exec 3<&0  0<<EOF
 10`${command}`
 11EOF
 12
 13while read line
 14do
 15    :
 16    count=`expr ${count} + 1`
 17done
 18
 19# exec 0<&3: FD3 に複製した標準入力 (FD0) を復帰
 20# exec 3<&-: FD3 をクローズ</i>
 21exec 0<&3 3<&-
 22
 23echo ${count}
    

もう一点は子プロセスで親プロセスの変数値を変更する方法。
こちらはプロセスが別になってしまうとファイルを使うしかないので、 同じプロセス内で関数呼び出しとして対応する方法が汎用的ではないだろうか。

  1#!/bin/sh
  2# eval を利用して呼び元の変数を設定する
  3
  4default="デフォルト値"
  5
  6sub()
  7{
  8
  9    local   _val
 10
 11    :
 12    _val="設定したい値"
 13
 14    eval "${1}='${_val:-${default}}'"
 15
 16}
 17
 18value="元の値"
 19
 20sub value
 21
 22echo ${value}
    

ちなみに上のリンク元にある parent.sh の中の処理で ${tmp_file} の内容を for ループで eval しているが、 これはシェルビルトインの . もしくは source を利用して . ${tmp_file} としても同一の結果が得られるので楽だと思う。

  1#!/bin/sh
  2
  3g1="aa"
  4g2="bb"
  5
  6tmp_file=`mktemp /tmp/ps.XXXXXX`
  7export tmp_file
  8
  9./child.sh    # child.sh で、上で設定した変数 g1, g2 の値を変更する
 10
 11# for v in `cat $tmp_file`; do
 12#   eval $v
 13# done
 14# ${tmp_file} の内容は name='value' 形式が保証されているので
 15# ファイル自体を `.' コマンドで読み込むだけで
 16# 行毎に eval を実行しなくてもシェル変数に代入された値が利用できる
 17
 18if [ -f ${tmp_file} ]
 19then
 20    . ${fmp_file}
 21    rm -f ${tmp_file}
 22fi
 23
 24echo $g1 #=> cc に変更された
 25echo $g2 #=> dd に変更された
    
ブログに直接コメントしたかったのだが、 はてなのアカウントが無いので申し訳ないがここで意見させて頂く。

2011/11/24

こどもの国

朝から好天に恵まれてぽかぽかな冬の休日を無駄にするのは勿体ないので、 かねてから気になっていた「こどもの国」に家族で出かけてみた。
行く前は「こどもの国」という名称から 『どうせ地方にありがちな子供向けのしょぼい遊園地の類だろう』等と 高をくくっていたのだが、実際に行ってみると大違い。 東京都と神奈川県にまたがる広大な敷地が、 自然の地形や環境上手に活かさて大人でも十分楽しめる遊園となっていて、 良い意味で期待が裏切られた。
あまりに広すぎるので一日では回りきれず 全体の半分程度を結構な駆け足で巡っただけなのだが、 それでも地面に自由に落書きできる広場や 本格的な牧場やポニーへの乗馬体験、 伊豆のサイクルスポーツセンターを彷彿とさせる様な 様々な変わり種自転車を集めた施設など盛りだくさんの内容だった。

Image: img_1475.jpg

母子で乗馬初体験

しかも牧場では定番のソフトクリームや 首都圏で随一生産されるらしい牛乳も楽しめる。

Image: img_1494.jpg

カーナンバー #27 の J.Alesiを彷彿とさせるドライビング

休日は道路も駐車場も混雑するだろうと電車で出かけたのだが、 2 度の乗り換えがあるが 1 時間かからない程度なので これからも是非出かけてみようと思う。

2011/11/16

メモリリークチェッカー

c で daemon 動作するサーバを作っていると malloc (3) などで動的に確保したメモリの free (3) 忘れによる いわゆるメモリリークを防ぐ事が非常に重要になってくる。
この様なメモリリークを防止するために役立つ 様々なツールが世の中には沢山存在しており それぞれ非常に有用ではあるのだが、 いざ利用しようと思うと割と面倒な作業が発生したり、 自分の求めている機能に対して明らかにオーバースペックだったりするので、 自分の用途に合わせて簡単に使える『俺様ツール』を作ってみた。

動作原理は簡単で malloc (3) や free (3) したアドレスを ログに出力して、 後からログを解析してメモリの確保と解放が対になっていない部分を 抽出するだけである。
そのためにまずは元となるソースコードを修正して、 malloc (3) や free (3) を独自に作成した wrapper 関数に置換えて 確保、解放したアドレスをログに出力する機能を組込む必要があるのだが、 malloc (3) などはエラー処理を含めて共通化するために あらかじめ wrapper 関数化されている場合が多いと思うので、 この部分はフォーマットを決めるだけで割りと簡単に追加できると思う。
今回は syslog (3) を利用して malloc (3)、strdup (3)、 free (3) で確保/解放するアドレスを出力した。

  1/*
  2 * malloc() の wrapper
  3 */
  4void    *mymalloc(size_t size)
  5{
  6
  7    void    *p;
  8
  9    if(!(p = malloc(size)))
 10        /* エラー処理 */;
 11    syslog(LOG_DEBUG, "malloc: %p\n", p);
 12
 13    return(p);
 14
 15}
 16
 17/*
 18 * strdup() の wrapper
 19 */
 20char    *mystrdup(const char *s)
 21{
 22
 23    char    *p = NULL;
 24
 25    if(s){
 26        if((p = strdup(s)))
 27            syslog(LOG_DEBUG, "strdup: %p\n", p);
 28        else
 29            /* エラー処理 */;
 30    }
 31
 32    return(p);
 33
 34}
 35
 36/*
 37 * free() の wrapper
 38 */
 39void    myfree(void *p)
 40{
 41
 42    if(p){
 43        free(p);
 44        syslog(LOG_DEBUG, "free: %p\n", p);
 45    }
 46
 47}
    

次に出力されたログの解析処理であるが、 確保したメモリのアドレスをキーとしたハッシュテーブルを利用したいので 入力行の解析やハッシュテーブルが簡単に利用できる言語として 今回はコマンドライン版の php (1) を利用してみた。
もちろん awk (1) を駆使したり perl (1) を利用しても問題ない。

  1<?php
  2    /*
  3     * Copyright (c) 2011 Mitzyuki IMAIZUMI, All rights reserved.
  4     *
  5     * $Id: memcheck.php 1677 2011-10-12 06:58:03Z mitz $
  6     */
  7
  8    /* 冗長指定 */
  9    if($argv[1] == "-v"){
 10        $verbose = 1;
 11        array_shift($argv);
 12    }
 13
 14    if($fp = fopen($argv[1], "r")){
 15        $line = 0;
 16        while($buf = fgets($fp, 1024)){
 17            $buf = ltrim($buf);
 18            $line++;
 19            /*
 20             * malloc か strdup か free を含む行の場合
 21             * コマンドを配列 $p[0] に、アドレスを配列 $p[1] に格納する
 22             */
 23            if(preg_match("/^(malloc|strdup|free):\s(.*)/", $buf, $p))
 24                /* 解放処理 */
 25                if($p[1] == "free")
 26                    /* 確保済みテーブルに解放アドレスが存在する場合 */
 27                    if($alloc[$p[2]]){
 28                        if($verbose)
 29                            printf("%s: % 8d -> % 8d\n", $p[2], $alloc[$p[2]], $line);
 30                        $alloc[$p[2]] = 0;
 31                    }
 32
 33                    /* 確保済みテーブルに解放アドレスが存在しない場合 */
 34                    else
 35                        printf("%s: unknown free at % 8d\n", $p[2], $line);
 36                else
 37                /* アドレスをキーとしたハッシュテーブルに行番号を格納 */
 38                    $alloc[$p[2]] = $line;
 39
 40        }
 41        fclose($fp);
 42
 43        foreach($alloc as $k => $v)
 44            if($v)
 45                printf("%s: NOT free (% 8d)\n", $k, $v);
 46    }
 47?>
    
このスクリプトを実行する事により malloc(3) もしくは strdup(3) で確保したメモリが解放されていない場合、 もしくは確保していないメモリを解放した場合が簡単に発見可能である。

これらは自分が必要とする機能のみを簡単に実装したものであり、 例えば解放していない事を意図しているメモリまで警告されてしまう等、 汎用的に使える事を目指したツールでは勿論ない。 ただ、日頃発生しうる面倒な作業がちょっとの工夫で 多少なりとも楽になるだろう例の一つとして公開してみた次第である。

2011/11/28 追記

awk (1) 版の方が汎用的なので簡単に作成してみた。 処理内容は上記 php (1) 版と同じである。
  1#!/bin/sh
  2
  3if [ "${1}" = "-v" ]
  4then
  5    verbose=true
  6    shift
  7fi
  8
  9awk '
 10    /^(malloc|strdup)/{
 11        alloc[$4] = NR;
 12    }
 13    /^free/{
 14        if(alloc[$4]){
 15            if("'${verbose:-false}'" == "true")
 16                printf("% 5d %s: % 5d\n", NR, $4, $alloc[$4]);
 17            alloc[$4] = 0;
 18        }
 19        else
 20            printf("% 5d %s: unknown free.\n", NR, $4);
 21    }
 22    END{
 23        for(i in alloc)
 24            if(alloc[i])
 25                printf("% 5d %s: NOT free.\n", alloc[i], i);
 26    }
 27' ${1} | sort ${2}
    

2011/10/30

Dear my Princess


May your Birthday, bring loads of joyful and sweet memories in your life. May you have a great and successful year ahead. Happy Birthday.

2011/10/18

電源関係の小物たち

いつも鞄に入れて持ち歩いている電源達関係の小物

Image: RIMG0456.JPG

電源達

  1. Apple 純正の AC アダプタ
  2. 普段から MacBookAir を持ち歩いているので、 Apple 純正の AC アダプタは必須 (IBM のバンドでまとめてあるのは愛嬌です)。

  3. USB 電源アダプタ
  4. 携帯電話や BlueTooth 機器など USB から充電できる機器が増えているので、 100V コンセントから USB の 5V を出力するアダプタも何かと便利。

  5. HyperMac
  6. 特許の関係で入手が不可になった HyperMac とそのケーブル。 これは MacBookAir からは通常の電源に見えるので、 純正のエアラインアダプタとは異なり充電もできる優れもの。 このおかげでお世辞にも長いとは言えない MacBookAir の駆動時間が 飛躍的に向上出来るのでモバイルには必須とも言えるアイテム。
    Apple も特許が大切なのは判るんだけど、 こういう素晴らしい商品はライセンスするとか対応を考えて欲しいと思う。

  7. Griffin の USB Mini-Cableset。
  8. Image: RIMG0365.JPG

    Griffin の USB Mini-Cableset
    一般的な USB の A 端子コネクタを Mini-USB、Micro-USB、 そして iPod 用の端子に変換するためのケーブルセットなのだが、 短めのケーブルなので収納に困らず邪魔にもならない。 普段から一緒に持ち歩いている iPod や Jawbone の BlueTooth ヘッドセットなど、 殆どの携帯機器の接続や充電が可能になるので非常に便利。

2011/09/17

Mac OS X Lion on VMware Fusion 4

すっかり世間の話題からは乗り遅れた感があるが、 そろそろ Mac OS X Lion を使ってみたくなってきた。
しかし、現在使用している Snow Leopard から 操作性が大きく変更になったと噂で聞いているので、 自宅でメイン環境として利用している MacBook Pro や 職場で生活環境、かつ開発環境として利用している iMac 27″ に Lion を導入する事は躊躇していた。
しかし、Mac OS X Lion をゲスト OS として正式にサポートした VMware Fusion 4 が発売されたので、 まずは VMware Fusion 4 の仮想環境に Mac OS X Lion をインストールして 操作性などを検証してみる。

少なくとも現状では旧バージョンの VMware Fusion からの 優待アップグレードなどは存在しない様なので新規購入する必要がある様だ。

I have a previous version of Fusion (1.x, 2.x, or 3.x.). Am I eligible to purchase an upgrade to Fusion 4?

There is no upgrade option for VMware Fusion 4. You may purchase a full license from our VMware online store. Licenses cost $49.99 USD (for a limited time only).

VMware Knowledge Baseより

期間限定ではあるが新規購入でも 49.99 USD と格安なので アップグレード並の低価格ではあるが…。

VMware Fusion は日本では以前より act2 が正規代理店として発売しているが、 MacUpdate のクーポン を利用して直接 VMware 社のサイトから USD の決済でダウンロード購入すると 10 USD ディスカウントとなり 39.99 USD で購入が可能となるので、 迷わず VMware 社サイトのオンラインストアにてダウンロード版を購入する。
ちなみに VMware Fusion は完全に国際化されているので、 日本で購入しなくてもインストーラからちゃんと日本語で表示される。

円高なので約 3,000 円程度で最新の仮想環境が入手できるのは素晴らしい。
Mac OS X Lion は AppStore からこちらもダウンロード販売で購入する。
こちらは円高の恩恵は受けられなかったのだが、 元々安価で提供されているのでそれほど気にならない。

VMware Fusion 4 を起動して新規仮想マシンアシスタントを起動したら、 インストールメディアの選択画面でダウンロード購入した Mac OS X Lion のインストーラを指定すれば簡単にインストールでき、 Mac OS X Lion の動作する検証用の仮想環境が構築できる。

肝心の Mac OS X Lion の操作性だが、 今は慣れていないのでまごつく事も多々あるのだが、 慣れれば良いのかな?というのが現状の感想。
もう暫く仮想環境で Lion の使い方に慣れたら 実マシンを Lion に移行してみようかとは思っている。

2011/09/09

Bowers & Wilkins C5

普段使いのヘッドフォンのケーブルが断線してしまったので、 発表されたばかりの Bowers & Wilkins 初のカナル型ヘッドフォン C5 を 試聴もしないまま購入する事にした。 購入時は日本未発売で円高の後押しもあったのでアメリカから個人輸入したのだが、 国内で購入するよりは随分と安く済んだ。
故障時の保証や言葉の問題など、 海外から直接個人輸入する事にはデメリットもあるので万人に勧められはしないが、 金額以外のメリットを享受できる場合もあるので 悪くない選択肢の一つだとはおもう。

Image: RIMG0352.JPG

そこそこ高級感のあるパッケージ

新品の状態で聴いてみた印象は音場は結構広がりがある感じだが、 新品故の固さというかドンシャリ感が強い感じ。
とは言っても聴き疲れするタイプの音質ではないし、 今の段階でも上品な感じの低音がしっかり鳴っているので、 今後のエージングに期待してみる。

Image: RIMG0358.JPG

マイクロ多孔質フィルタとセキュアループ

外観の特徴にもなっている筐体外側のマイクロ多孔質フィルターの効果なのか 装着した時の耳への圧迫感が随分軽減されていて、 カナル型なのにも関わらず長時間装着していても苦にならない快適さだと思う。
もう一つ特徴的な外観を形成しているセキュア・ループ・デザインは、 耳たぶの内側にあてる事で装着時のフィット感を高める造りとなっている。 簡単にサイズも調節可能だし見た目も特徴的なので悪くない。
ケーブルの途中に組み込まれたリモコンは 手持ちの iPod や MacBook Pro の iTunes を操作できるので意外と便利だ。
リモコンはボタンが 3 個なので 再生・停止とボリューム操作だけだと思っていたのだが、 ちゃんとマニュアルを読むと 2 回クリックで次の曲、 3 回クリックで前の曲へのスキップも可能だった。

ピンクノイズなどで暫くエージングした後も第一印象とそうは変わらない感じだが、 固めにドンシャリと響いていたカドが丸まったと思う。 上品に響く低音と抜けの良い高音、それから広い音場とあいまって とても優しく聴き疲れしない良質な音になっていると思う。


Copyright © 2008-2020 Mitzyuki IMAIZUMI. All rights reserved.