2013年12月9日月曜日

進捗どうでしょう

「進捗どうですか」と聞いて「進捗ダメです」って答えるネタが流行っているみたい。元ネタは良く知らないのだけど。
この記事は進捗Advent Calendar 2013 9日目向けのものです。アドベントカレンダーなるものに初めて参加してみます。

修士論文

僕の進捗といえば修論の話をしなくてはいけません。なぜなら修士2年生だからです。そう、もう数ヶ月で卒業…。大学に入学して6年、ああ、小学校時代と同じ長さなのか!そりゃすんげえ!

修論は論文誌に投稿するのが12月中、学校に提出するのが1月後半という目標です。
単純なページ数的進捗で言えば、論文誌用の論文の方は2/6ページ書きました。執筆が捗るときと捗らないときの波が結構ありますけど、残りも頑張ります。ちなみにC-Helperが僕の研究です。

マイスタイル

僕が論文書くときのスタイルなどを書いておきます。「我も同じじゃ」とか「こうしたほうが良いよ」などありましたらコメントで教えてください。参考にさせていただくかもしれません!

音楽

BGMをかけつつ文章を書くのが好きです。電子音がピコピコするアニソン系の曲、東方JAZZアレンジ系、UKロックなど聴きます。日本語の歌詞が聞き取りやすい曲も好きですが、作業効率は落ちる気がします。
そうそう、最近はDiverse Systemのworks.3を買いまして、修論のお供に良く使ってます。アルバムタイトルの通り、結構優秀な作業用BGMだと思います。

場所

執筆活動をする場所も僕には重要です。僕は自宅ではゲームなどやってしまって執筆が捗ったためしがありません。比較的集中できるのはドトールなどのカフェや通学電車です。自宅以外だとお気に入りのゲームも無いですし、適度に人の目(カフェ席で寝てたら恥ずかしいので寝ないですみます)もありますから。
さらに付加効果として、カフェでMacBook Airを広げると多少優越感があります。Haswell搭載のノートPCにすれば、一日中電源なしでカフェを転々として執筆活動にいそしめます。

道具

Vim+TeXをターミナルから使って論文書いてます。Vimで.texファイルを保存するたびにmakeが非同期で走るように.vimrcを設定してあり、自動でTeXコンパイルされます。PDFのプレビューにSkimを使えば、ファイルの更新を自動で検出して再読み込みしてくれるので便利です。しかも、再読込時に他のウィンドウよりも手前、ターミナルよりも後ろという超絶妙な位置に再配置されるので、非常に使いやすい。おすすめ。

修論の同士たち、一緒に頑張りましょう。


さて、明日は wraith13 さんの担当で御座います。進捗は如何でしょう?

2013年11月22日金曜日

USBメモリはローカルディスク?リムーバブルメディア?

USBメモリをWindowsマシンに挿したとき、ローカルディスクになってしまう問題があります。または、無理やりローカルディスクとして認識させたい場合もあるでしょう(今回調べたのは、後者の理由です)。

少し調べたところ、USBメモリがリムーバブルメディアとして認識されるのはATAのIDENTIFY DEVICEコマンドの戻り値のRemovable Media Bitが1だからだそうです。

リムーバブル メディア デバイス設定は、SCSI Inquiry コマンドへの SCSI Inquiry Data 応答内に含まれたフラグです。バイト 1 のビット 7 (インデックスは 0 から開始) は、Removable Media Bit (RMB) です。ゼロに設定された RMB は、デバイスがリムーバブル メディア デバイスではないことを示します。1 に設定された RMB は、デバイスがリムーバブル メディア デバイスであることを示します。

flip removable media bit とググると、んもうたくさんの質問や記事が出てきます。皆さんUSBメモリにパーティションを作りたくてうずうずしているのでしょう。

漁ってみた中で一番確実そうな方法は "Lexar BootIt utility" を使う方法でした(まだ試していませんが)。LexarはUSBメモリのメーカーで、恐らく自社製品用にツールを作ったのだと思います。ということで、お店でLexarのTwistTurnなるUSBメモリを買ってきました。(Lexarのツールを使ってみたらここに追記予定)


Tips for USB pen drives によれば、「Removable」は本来、フロッピーやZIPドライブ、フラッシュカードリーダーなど、取り外し可能メディアを持つ機器を表すそうです。USBメモリがRMB=1になっているのは厳密には正しくないけれども、ほとんどすべてのUSBメモリがそうなってしまっているのだそうです(反対にUSBハードドライブはRMB=0になっています)。

なぜUSBハードディスクはリムーバブルでないのにUSBメモリはリムーバブルなのかは理解できませんが、現実的に市場の製品がそうなってしまっているのだから仕方がない。注意して製品選びするしかなさそうです。

Lexar BootIt utilityを試したらこの記事を修正するつもりです。

2013年10月15日火曜日

OS X Mountain Lion で i686-elf 向け GCC をビルドする

Xcode の Command Line Tools でインストールされる gcc コマンドは llvm-gcc なので、本当の GNU C Compiler ではありません。 Mac でクロスコンパイル用の GCC をビルドするためには、本物の gcc コマンドが必要です。
Mountain Lionユーザのためのクロスコンパイラビルド - Handwriting を読んでこの事実を知りました(それまで5回ぐらいクロスコンパイル用 GCC をビルドしようとして失敗していました)。

以下、ビルド手順メモ

ネイティブ用 GCC ビルド

クロスコンパイル用 GCC をビルドするための GCC をビルドします。A bare-metal x86-cross-compiler on Mountain Lion | The Intobooks や、そこからリンクされている Compiling gcc-4.7.1 on Mac OSX Lion が参考になりました。これらの記事の手順は僕の Mountain Lion でも使えました。

各種ソースコードのダウンロードと展開

$ cd ~
$ mkdir gcc-4.8.1
$ cd gcc-4.8.1
$ curl -O http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-4.8.1/gcc-4.8.1.tar.gz
$ curl -O http://ftp.tsukuba.wide.ad.jp/software/gmp/gmp-5.1.3.tar.gz
$ curl -O http://ftp.tsukuba.wide.ad.jp/software/mpfr/mpfr-3.1.2.tar.gz
$ curl -O http://ftp.tsukuba.wide.ad.jp/software/mpc/mpc-1.0.1.tar.gz
$ tar zxvf gcc-4.8.1.tar.gz
$ tar xzvf gmp-5.1.3.tar.gz 
$ tar xzvf mpfr-3.1.2.tar.gz
$ tar xzvf mpc-1.0.1.tar.gz

ビルドとインストール

ビルドするまえに環境変数 PATH の値をなるべくシンプルに調整するとミスがありません。PATHを調整し終えたらいざビルド。

GMP
$ mkdir gmp-build
$ cd gmp-build
$ ../gmp-5.1.3/configure --prefix=/Users/uchan/gcc-4.8.1/ --enable-cxx
$ make -j4
$ make install
$ cd ..

MPFR
$ mkdir mpfr-build
$ cd mpfr-build
$ ../mpfr-3.1.2/configure --prefix=/Users/uchan/gcc-4.8.1 --with-gmp=/Users/uchan/gcc-4.8.1
$ make -j4
$ make install
$ cd ..

MPC
$ mkdir mpc-build
$ cd mpc-build
$ ../mpc-1.0.1/configure --prefix=/Users/uchan/gcc-4.8.1 --with-gmp=/Users/uchan/gcc-4.8.1 --with-mpfr=/Users/uchan/gcc-4.8.1
$ make -j4
$ make install
$ cd ..

GCC
$ mkdir gcc-build
$ cd gcc-build
$ ../gcc-4.8.1/configure --prefix=/Users/uchan/gcc-4.8.1 --enable-checking=release --with-gmp=/Users/uchan/gcc-4.8.1 --with-mpfr=/Users/uchan/gcc-4.8.1 --with-mpc=/Users/uchan/gcc-4.8.1 --enable-languages=c,c++
$ make -j4
$ make install
$ cd ..

以上でクロスコンパイル用 GCC をビルドするためのネイティブ GCC が出来上がりました!(ややこしい(^^;

さて、やっとクロスコンパイル用 GCC のビルドです。まず PATH の調整など。先ほどビルドした GCC のパスと、クロスコンパイル用 GCC のパスも忘れず通します。GCC, GMP, MPFR, MPC のソースは先ほど展開したものを再利用します。
$ export PATH=$HOME/i686-elf-gcc-4.8.1/bin:$HOME/gcc-4.8.1/bin:$PATH
$ cd ~
$ mkdir i686-elf-gcc-4.8.1
$ cd i686-elf-gcc-4.8.1
$ mkdir src
$ cd src
$ ln -s ~/gcc-4.8.1/src/gcc-4.8.1 ./
$ ln -s ~/gcc-4.8.1/src/gmp-5.1.3 ./
$ ln -s ~/gcc-4.8.1/src/mpfr-3.1.2 ./
$ ln -s ~/gcc-4.8.1/src/mpc-1.0.1 ./

binutils
$ curl -O http://ftp.tsukuba.wide.ad.jp/software/binutils/releases/binutils-2.23.2.tar.bz2
$ tar xjvf binutils-2.23.2.tar.bz2
$ mkdir binutils-build
$ cd binutils-build
$ ../binutils-2.23.2/configure --prefix=/Users/uchan/i686-elf-gcc-4.8.1 --target=i686-elf
$ make -j4
$ make install
$ cd ..

GCC
$ mkdir gcc-build
$ cd gcc-build
$ ../gcc-4.8.1/configure --prefix=/Users/uchan/i686-elf-gcc-4.8.1 --target=i686-elf --enable-languages=c,c++ --without-headers
$ make -j4 all-gcc
$ make install-gcc

必要な configure オプションについては 開発環境(自作OS) - こうじのがく まとめ(自作OS、ホームページ作成) を参考にしました。
  • --without-headers : 自作 OS 開発には標準ヘッダファイルや標準ライブラリは要りませんので、これを指定しておきましょう。
make に all-gcc を指定するのが重要です。これを指定しないと make の途中でエラーが発生するかもしれません。(実際、 libstdc++ のビルドに失敗している様でした)

以上でクロスコンパイル用 GCC のインストールは完了です。やったね!

2013年10月11日金曜日

【自作OS】 Bookmarks

自作OSを作る上で参考になりそうなサイトを見つけたら追記していきます。主に個人用メモ。

起動処理,MBR

HDDの話 : CHS・LBAアドレスの話
MBR(Master Boot Recode)の構造 : MBRの何処に何が書いてあるか
Partition types : パーティションタイプのリスト

ATA in x86 RealMode (BIOS) : リアルモードでの BIOS の色々なお話。フロッピーの BPB に書かれている "Sectors per Track" や "Number of Heads" の値は「ほとんど常に間違っている」という記述に笑ってしまった(笑)
INT 13 Drive Type : BIOSは起動直後に DL レジスタにドライブ番号を格納してくれるというお話(でもこの番号は信頼性がない場合があり、MSのIPLは番号決め打ちしているという情報をいただいた)

Windows NT ブート処理とハード ディスクの制限 : MS公式サイト。Windows NT の IPL のディスク読み取り処理は BIOS int 0x13 にのみ依存することなどが書いてある

NASM

The Netwide Assembler: NASM : nasm の -f オプションに応じてビット数がデフォルトで設定されており、通常は明示的な BITS ディレクティブは必要ない。

ELF

Executable and Linkable Format - Wikipedia
ELF

リンカ ld

GNU リンカ LD の使い方
NASK環境からの解脱

building binutils

[Qemu-devel] [PATCH] configure: disable clang -Wstring-plus-int warning

メモリマップ

(AT)memorymap - OS-Wiki
Memory Map (x86) - OSDev Wiki

C++対応

C++ - OSDev Wiki

【自作OS】USBメモリからブートする

昨日あるチャットで自作OSの話題になったとき、最近のパソコンにはフロッピーが無い、USBメモリから起動できたらいいよね、という話が出ました。

気になったのでやってみました。


ブートセクタ - Wikipedia によれば、どんな起動デバイスでも BIOS は先頭 512 バイトを 0x7c00 番地に配置して実行してくれるらしい。

Hello World を表示する 512 バイトのバイナリを用意して、それを USB メモリの MBR に書き込んでしまえばいいはず。ちょうど良いことに「30日でできる! OS自作入門」の2日目3節で Hello World を表示するだけの 512 バイトのバイナリを作っていますので、これを利用することにしました。

MBR への書き込みには 【取り扱い注意】USB(メモリ)ブート関連ツール で紹介されている BOOTICE というツールを使いました。BOOTICE の画面で ProcessMBR → Restore MBR を選択し、上記の 512 バイトバイナリを選択すれば書き込めます。楽ちんだね!

壊れてもいい USB メモリを使ってくださいね!

で MBR への書き込みが完了した USB メモリをパソコンに刺して起動させれば、ほら! Hello World が出ました!

2013年9月6日金曜日

【Java】cannot be resolved to a type エラーと CLASSPATH の順序

Java の クラスパス の設定でちょっと躓いたので記録。

javac や java コマンドの実行時にクラスパスを指定するには2通りのやり方がある。 -classpath オプションを使う方法と CLASSPATH 環境変数を使う方法だ。今回検証したのは環境変数による設定のみである。

発生した問題を説明する。依存ライブラリの jar ファイルを全て CLASSPATH に含めて java コマンドを実行しても、コンパイルした bin ディレクトリ外では以下の様なエラーが発生した。

Exception in thread "main" java.lang.Error: Unresolved compilation problems: 
 Options cannot be resolved to a type
 Options cannot be resolved to a type
 CommandLineParser cannot be resolved to a type
 PosixParser cannot be resolved to a type
 CommandLine cannot be resolved to a type
 Option cannot be resolved to a type
 ParseException cannot be resolved to a type

 at com.github.uchan_nos.c_helper.Launcher.main(Launcher.java:32)

コンパイル時はエラーがなく、さらに bin ディレクトリで java コマンドを実行すれば正常に実行されるのに、 java コマンドを実行するときのカレントディレクトリが異なるとダメになる。

この時のクラスパスの設定は次。
export CLASSPATH=`python ~/gitrepos/c-helper/tools/classpath.py /Applications/eclipse/plugins`:~/java/lib/commons-cli-1.2/commons-cli-1.2.jar:~/gitrepos/c-helper/bin

`と`で囲まれた python コマンドは、依存している jar ファイルの名前をコロン区切りにするためのもの。その後ろに追加で依存する commons-cli-1.2.jar ファイルを指定した。

このようなときは、クラスパスの順序を変えれば解決するかもしれない。今回の場合は以下のように修正したら解決した。
export CLASSPATH=~/java/lib/commons-cli-1.2/commons-cli-1.2.jar:~/gitrepos/c-helper/bin:`python ~/gitrepos/c-helper/tools/classpath.py /Applications/eclipse/plugins`

私自身クラスパスの仕組みをはっきりと把握できていないため、今回の対処法が全ての場合で有効かは分からないが、今回の場合はこれが特効薬だった。

2013年8月16日金曜日

OS X Mountain Lion + Python 3 + Beautiful Soup 4

OS X Mountain Lion 上で動く Python 3 に Beautiful Soup 4 をインストールしようとしたら嵌ったのでメモ。

Python 3.3.2 (HomeBrew でインストールしたもの)
Beautiful Soup 4.3.0

上手く行ったインストール方法


$ sudo pip3 install beautifulsoup4
$ cd /usr/local/lib/python3.3/site-packages/
$ sudo 2to3-3.3 -w bs4

問題

pip3 でインストールするだけだと Beautiful Soup をインポートするときに SyntaxError 例外が発生する。

uchan@uchan-mba:site-packages$ python3
Python 3.3.2 (default, Jul 11 2013, 15:15:27) 
[GCC 4.2.1 Compatible Apple LLVM 4.2 (clang-425.0.28)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from bs4 import BeautifulSoup4
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "./bs4/__init__.py", line 392
    print soup.prettify()
             ^
SyntaxError: invalid syntax

2to3-3.3 コマンドを手動で実行することで、ライブラリのソースコードを Python 3.3 向けに修正することができる。(インストーラが自動実行しないのはライブラリのバグかもしれない)

2013年7月29日月曜日

Qt Creator で Qt Quick アプリケーションを作ると QML ファイルが読み込めない

OS X Mountain Lion + Qt 5.1.0 + Qt Creator 2.8.0 という環境で開発しています。

Qt Creator で ファイル > ファイル/プロジェクトの新規作成 > Qt Quick 2 Application (Built-in Types) からプロジェクトを作ると main.qml, main.cpp, qtquick2applicationviewer.cpp が含まれたプロジェクトが生成されます。各ファイルに関する説明は QtQuick での C++ × QML バインディングについてまとめてみた を読むといいです。僕もこれを参考に勉強しています。

しかし、初期状態で作成したプロジェクトを実行しようとしても main.qml ファイルの読込エラーが発生してしまいます。原因を調査したところ、どうやらビルド成果物のパスに日本語が含まれると QML ファイルのコピーに失敗してしまうようです。

プロジェクトを作るときのウィザードで日本語を含むパスを指定する(画像参照)と QML ファイルのコピーに失敗しますので、設定を変えて(「デスクトップ」を「Desktop」にでも変更しましょう)再度プロジェクトを生成すると上手く行きます。エラーに悩まされている人は参考にしてください。

成果物へのパスに日本語が含まれている 
「デスクトップ」を「Desktop」に変えた
プロジェクトを再度作成したら英語になった!

ちなみに、元々コピー対象ではないリソースなどをバンドル(hoge.appのこと)に含めるには How to add resource files to an OS X application bundle という方法があるようです。この方法を使っても main.qml が見つからないエラーを解決できます。ただ、この方法は上手くやらないとプロジェクトファイルが OS X 専用になってしまうと思います。なるべく先述の設定変更で対処するのがいいでしょう。

2013年7月23日火曜日

Qt 5.1 + QML + qmlscene

QML でプログラミングを始めよう を参考に QML の勉強を始めました。
ボタンの表示からテキストエディタの作成、C++との連携など一連の内容が書いてあって参考になりそうな感じです。

Qt 5から QML ファイルのプレビュー方法が変わったらしく、ちょっとはまったのでメモしておきます。

上記サイトでは QMLViewer を用いてプレビューを行なっていますが、どうやら Qt 5 からは qmlscene コマンドを使うようです。BeagleBoard 向け Qt 5

公式の First Steps with QML | QtDoc 5.1 を見たら qmlscene を使うんだよとちゃんと書いてありました。お恥ずかしい (^^;

ということで、以下の様な QML ファイルを作って qmlscene しましょう。

-- win.qml --
import QtQuick 2.0

Rectangle {
  id: simplebutton
  color: "gray"
  width: 150
  height: 75

  Text {
    id: buttonlabel
    anchors.centerIn: parent
    text: "hello!!"
  }
}

$ qmlscene win.qml

2013年7月22日月曜日

Qt 5.1 on Mac OS X Mountain Lion

GUIアプリを作ることになりまして、久しぶりに Qt を使おうかなと思ったのでした。
調べたら Qt 5.1 がリリースされていましたので Mountain Lion への入れ方などメモします。

インストール

既に Homebrew で Qt 4.8.4 を入れていたので干渉を避けるため、ソースからビルドすることにしました。
Qt Project から qt-everywhere-opensource-src-5.1.0.tar.gz をダウンロードしビルドします。
ビルド方法は Installation | QtDoc 5.1 が参考になります。

$ tar xzvf qt-everywhere-opensource-src-5.1.0.tar.gz
$ cd qt-everywhere-opensource-src-5.1.0
$ ./configure
$ make
$ sudo make -j1 install

途中でライセンスの選択を聞かれたので LPGL 版を選択しました。最後に PATH の調整をして終わりです。~/.bashrc に次を書き加えればいいでしょう。

export PATH=/usr/local/Qt-5.1.0/bin:$PATH

最後に希望のバージョンが入っていることを確認します。

$ qmake -v

QMake version 3.0
Using Qt version 5.1.0 in /usr/local/Qt-5.1.0/lib

Hello, World

Qt で画像をフルスクリーン表示する を参考にテストプログラムを作りました。

-- main.cpp --
#include <QApplication>
#include <QPixmap>
#include <QLabel>

int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    QPixmap pixmap("/path/to/picture.jpg");
    QLabel screen;
    screen.setPixmap(pixmap);
    screen.show();

    return app.exec();
}
-- main.cpp --

ソースコードを準備したらプロジェクトファイルを生成します。そのプロジェクトのビルドに必要なライブラリや追加のインクルードパス、使用する Qt のモジュールなどを記述するためのファイルです。

$ qmake -project

Qt 5.1 から、どうやら GUI アプリを作る(QApplication クラスなどを使う)にはプロジェクトファイルの修正が必要なようです。生成されたプロジェクトファイルに次の1行を書き加えます。
この修正をしないとヘッダファイルが見つからないと言われたり、なんとか解決しても Mac: Undefined symbols for architecture x86_64: “QApplication::palette()”, referenced from: という感じのエラーが出てリンクできません。

QT += widgets

そうしたら Makefile を生成してビルドします。

$ qmake
$ make

アプリの起動は .app ファイルを起動しましょう。

$ open hoge.app

指定した画像が表示されたら成功です。

2013年6月19日水曜日

The project description file (.project) for ‘c-helper’ is missing

古い Mac から workspace をコピーしてきて、それを新しい Mac にインストールした Eclipse のワークスペースとして指定しました。
そうしたら、あるプロジェクトで "The project description file (.project) for ‘c-helper’ is missing" というエラーが出てしまいました。

同じようなエラーで悩んでいる人は結構居るみたいでした。
The project description file (.project) for my project is missing
Relocating Eclipse Projects: The project description file (.project) for XXX is missing
The project description file (.project) for ‘MyFlexProject’ is missing

プロジェクトをインポートし直すと治るよ(1つめの記事)とか、 .location ファイルを削除したら治るよ(2つめの記事)、という情報がありましたが、僕のケースではどちらもダメでした。

で、3つめの記事に書いてあった情報が役立ちました。
この記事は Flex Builder 3 についての記事ですが、 Eclipse にも当てはまるでしょう。

古いパソコンからワークスペースをコピーしてきて、 Eclipse がそのワークスペースを指すようにするのは間違った方法で、正しくはコピーしてきたワークスペースとは別のワークスペースを作って、プロジェクトをインポートするという方法だそうです。

とうことで、ワークスペースを新しく作って問題のプロジェクトをインポートしたら解決しました!

Xcode で gitk がインストールされない OS X Mountain Lion

新しい MacBook Air (2013 mid version)を買ったので、早速 Xcode 4.6.3 をインストールし、 Preferences > Download から Command Line Tools をインストールした。

しかし、どうやら gitk がインストールされていない。 git コマンドはインストールされたが、もしかしたら最新版の Xcode には gitk が含まれないのかもしれない。

ということで GitX http://gitx.frim.nl なるアプリをダウンロードしてみた。
最初に起動するとフォルダ選択画面になる。そこで .git が置いてあるフォルダ(または .git フォルダそのもの)を選択すれば、きれいなコミットグラフが表示される。

ターミナルから gitk と同じように呼び出して使いたいときは、 GitX を起動した状態で GitX > Enable Terminal Usage... を選択しよう。 /usr/bin/gitx がインストールされる。

2013年5月19日日曜日

【Eclipse】型 Foo のメソッド bar() はスーパークラスのメソッドをオーバーライドする必要があります


Eclipse に既存のプロジェクトをインポートしたら
型 Foo のメソッド bar() はスーパークラスのメソッドをオーバーライドする必要があります
というエラーがたくさん出ました。
ちゃんとその名前のメソッドを持ったインターフェースを implement してますし、そもそも他の Eclipse 環境ではこのエラー出ませんし。

と思ってググっていたらどうやらこれでした。
'Must Override a Superclass Method' Errors after importing a project into Eclipse

要するに、Eclipse はデフォルトで Java 1.5 を使おうとするのが原因らしいです。
Java 1.5 以前は、 @Override できるのは本当に「スーパークラス」にそのメソッドがある場合だけで、今回のようにインターフェースにあるメソッドは @Override 指定できないのです。(初めて知った)

ということで、Eclipse または個々のプロジェクトのデフォルトを Java 1.6 にすれば解決します。
Windows 版 Eclipse 4.2 なら
 プロジェクト > プロパティ > Java コンパイラー
または
 ウィンドウ > 設定 > Java > コンパイラー
の画面からコンパイラーの準拠レベルを指定できます。(下図を参照)

2013年4月4日木曜日

WebSocket onopenのイベントハンドラは必ず呼び出されるのか

WebSocket を勉強しています。

WebSocket には onopen, onmessage, onclose というイベントが用意されています。
こんな感じで使います。
var wstest = function() {
  var ws = new WebSocket("ws://localhost:8000/");

  // 1秒待つ
  var d1 = new Date().getTime();
  var d2 = new Date().getTime();
  while (d2 < d1 + 1000) {
    d2 = new Date().getTime();
  }

  // イベントハンドラ登録
  ws.onopen = function() {
    console.log("websocket opened");
  };
  ws.onmessage = function(e) {
    console.log(e.data);
  };
  ws.onclose = function() {
    console.log("websocket closed");
  };
};

1秒待つ部分は、今回の疑問を実験するために挿入しています。
new WebSocket でソケットを生成してからイベントハンドラの登録までのタイムラグが、どのような影響を与えるかを調べたかったのです。

僕の予想では、 new WebSocket で生成された直後からサーバーへの接続処理が始まって、イベントハンドラの登録はすでにソケットが開かれた後に行われ、結果としてイベントハンドラが呼ばれないはずでした。
しかし、予想に反して、ソケットの接続処理は1秒後に行われ、 onopen イベントがきちんと発生し、イベントハンドラが呼び出されました。
サーバー側でも、1秒後に onopen イベントが呼び出されていました。

どうやら、 new WebSocket した関数(wstest)を抜け出してからサーバーへの接続処理が行われるのでは、と推測できます。
この動作が WebSocket の規格なのか、たまたま Google Chrome ではそのように動いたのかは定かではありません。しかし、僕が調べた限り WebSocket の使い方を解説しているサイトには、 new WebSocket した後で onopen イベントハンドラを登録するやり方しか載っていませんでしたので、きっとそれが正規の方法なのだと思うことにします。

2013年3月31日日曜日

【Windows7】 コマンドプロンプトで関連付け制御

Windows7のファイルとアプリケーションの関連づけをコマンドプロンプトで行う方法

コマンドプロンプトで作業していて
> hoge.py foo bar
のようなことをやりたかった。
hoge.pyをpython.exeに関連付けつつ、hoge.pyに引数foo, barも渡したい。

エクスプローラなどからGUIで関連付けしちゃうと、hoge.pyをpython.exeに関連付けることはできるが、引数が渡らなくなっちゃう。

そこで、コマンドプロンプトからassoc, ftypeコマンドを使って関連付けを設定する。
設定変更は、管理者権限のあるコマンドプロンプトから実行する。

assoc

拡張子とファイルタイプを紐付ける

設定確認
> assoc .py
.py=Python.File

設定変更
> assoc .py=Python.File

ftype

ファイルタイプとアプリケーションを紐付ける

設定確認
> ftype Python.File
Python.File="C:\Python27\python.exe" "%1" %*

設定変更
> ftype Python.File="C:\Python27\python.exe" "%1" %*


GUIから設定した関連付けが残っているとそちらが優先されるようなので、削除しておこう。(以下リンク参照)

参考
[Windows] Pythonの関連付け設定
Windows 7(Vista)でファイルの関連付け情報を削除(解除)する

2013年3月18日月曜日

C-Helperの特長と使い方

先日リリースしたC-Helper(Uchan Note: C-Helperリリース 参照)の特長と使い方を説明します。

C-Helperの特長

C-Helperは、簡単な操作でC言語のソースコードを検査します。検査項目とサンプルコード、C-Helperの出力メッセージは以下のとおりです。
※出力メッセージは開発版であり、リリース版とは異なる場合があります。
  • char型変数への文字列代入
    char c;
    c = "+";
    
    メッセージ「char型変数に文字列を格納できません。 char型配列を検討してください。」
  • 警告を抑え込むキャスト
    printf("%s", (char *)getchar());
    
    メッセージ「式 getchar() が1つの文字を表しているなら %c を使えば表示可能です。」
  • 文字と文字列の比較
    int word;
    if (word == "+") puts("word is +");
    
    メッセージ「文字と文字列は比較できません。(1文字を表すには"ではなく'で囲みます。)」
  • ヘッダファイルでの実体定義
    test.h
    int g_x;
    
    test.c
    #include "test.h"
    
    メッセージ「ヘッダファイルには実体を定義すべきではありません。(extern宣言を用いてください。 (extern int g_x;) )」
  • 識別子の重複
    int x;
    void f(void) {
        int x;
    }
    
    メッセージ「識別子xが重複しています。」
  • インデントの乱れ
    void f(void) {
        int i;
        for (i=0; i<3; i++) {
        printf("%d\n", i);
        }
    }
    
    メッセージ「インデントが乱れています。スペース 8 個分インデントすべきです。」
  • メモリリーク
    void f(int flag) {
        char *p;
        p = malloc(123);
        if (flag) free(p);
    }
    
    メッセージ「メモリリークが発生する可能性があります。」
  • printfのパラメタ間違い
    printf("%d", 3.14);
    
    メッセージ「引数は!浮動小数点数型ですが %d は!符号付き整数型を期待しています。(浮動小数点数の表示には %f, %e, %g などが使えます。)」
  • returnの記述漏れ
    int f(void) {
        if (0) return 1;
    }
    
    メッセージ「return文がありません。」
  • scanfへの値渡し
    int x;
    scanf("%d", x);
    
    メッセージ「ポインタを渡す必要があります。(&を付けて変数へのポインタを取得します。(&x))」
  • 構造体宣言のセミコロン忘れ
    struct Foo {
        int bar;
    }
    int main(void) {
        return 0;
    }
    
    メッセージ「構造体の宣言にはセミコロンが必要です。」
  • 関数定義の余分なセミコロン
    int main(void);
    {
        return 0;
    }
    
    メッセージ「関数定義にはセミコロン ; を付けません。」
  • 動的に確保した配列に対するsizeof
    char *p = malloc(128);
    printf("%u", sizeof(p));
    
    メッセージ1「sizeof(p) は 128 ではなく 4 を返します (仮定6)。それは本当に意図したことですか?」
    メッセージ2「仮定6: ポインタ変数のサイズを 4 バイトと仮定しています。」
  • 定義されていない関数名の使用
    int main(void) {
        printf("hello, world!\n");
        return 0;
    }
    
    メッセージ「printf は宣言されていない関数名です。(stdio.h を #include してください。)」


C-Helperの使い方

ソースコードを記述して、C-Helperの起動アイコンをクリックします。
起動アイコン
下図の状態で起動アイコンをクリックすると、test.cがチェックされます。(main.cはチェックされません)

最前面にあるソースコードエディタに対して動作します。
上図のように、チェックしたいソースコードを最前面に表示しておいてください。

2013年3月11日月曜日

C-Helperリリース


サイボウズ・ラボユースでしばらく製作していた、初学者向けのC言語学習支援ツール "C-Helper" が、取り敢えず形になりましたのでリリースいたします。
https://github.com/uchan-nos/c-helper/blob/master/README.md

C-Helperは

  • 初学者が書いたソースコードを検査します
  • 間違いやすい項目を検査し、警告を表示します
  • 可能ならば修正案を提示します

C-Helperの検出項目の一覧はUchan Note: C-Helperの特長と使い方を御覧ください。

興味がある方、是非使ってみてください。
これからも時々バージョンアップさせるつもりです。

Eclipseプラグインですので、C-Helperを使うにはまずEclipseのダウンロードとインストールが必要です。
上記READMEに詳しいやり方を書きましたのでご覧ください。

C-Helperを使っていただき、是非アンケートにご協力ください。
https://docs.google.com/forms/d/1bdGMk4v-gFTAPq7C6s--pkpHi-5227vU4bZO1pjZ8hQ/viewform

2013年2月18日月曜日

【Eclipseプラグイン開発】 配布時に他プラグインへの依存をなくす

Eclipseプラグインの開発時と配布時の、他プラグインへの依存関係を変えたいことがあります。
例えば、開発時にJUnitを使ってテストをするような場合。
配布先ではテストをしないでしょうから、末端ユーザーの環境にJUnitプラグインがなくても大丈夫なようにしたい。
このように、開発時と配布時の依存関係を変えたいという要望があるでしょう。

まず基礎知識として、開発しているEclipseプラグインの依存設定はplugin.xmlで設定します。
マニフェストエディタでplugin.xmlを開けばDependenciesタブがあります(下図)。


Plug-in Dependencies - Help Eclipse Platform
を読むと、依存設定の"Optional"オプションを有効化すると、その依存プラグインが配布先環境に存在してもしなくても、配布したプラグインが実行できるそうです。

ということで、実際に試してみたところ、JUnitプラグインが存在しない環境でもC-Helperがインストール&実行できるようになりました。

2013年2月4日月曜日

【Vim】Markdownプレビュー用プラグインを入れる


OS X Mountain Lion で Vim に https://github.com/mattn/mkdpreview-vim を導入します。

プラグイン開発者さんのブログ記事 http://mattn.kaoriya.net/software/vim/20120208161751.htm

依存しているソフトウェアのインストール

ソースコードをコンパイルしてもいいんですが、面倒なのでHomebrewで。
$ brew install pyqt4
$ sudo easy_install markdown

上記のブログに依存しているソフトウェアが列挙されているのですが、markdownライブラリは一覧に含まれていませんでした。
しかしどうやら、mkdpreview-vimが裏で使っているらしいので、インストールしておきます。

Vimプラグインのインストール

mkdpreview-vimはwebapi-vimに依存しているらしいので、両方入れます。
僕はVundleを使っているので、以下のように書きました。
.vimrc
Bundle 'mattn/webapi-vim'
Bundle 'mattn/mkdpreview-vim'

そしたらVimから :BundleInstall でOK

プラグインの調整

brewでPyQt4を入れたので、このままではpythonが認識してくれません。
ということで mkdpreview-vim/static/mkdpreview.py をちょこっと改造します。

import os 
import sys 
import json 
import cgi 
import imp 
import signal 
from threading import Thread 
 
# add serch path 
sys.path.insert(0, '/usr/local/lib/python2.7/site-packages') 
from PyQt4.QtCore import * 
from PyQt4.QtGui import * 
from PyQt4.QtWebKit import * 
from PyQt4.QtNetwork import * 
from BaseHTTPServer import HTTPServer 
from SimpleHTTPServer import SimpleHTTPRequestHandler 

こんな感じで、PyQt4がインストールされたディレクトリをパスに追加しておきましょう。



2013/06/20追記

今 pyqt4 をインストールしようとしたら見つからないと言われました。どうやらパッケージ名が変わったようです。
$ brew install pyqt
でいけます。

さらに、インストール中にこんなメッセージが出ていたのに気づきました。

For non-homebrew python (2.x), you need to amend your PYTHONPATH like so:
  export PYTHONPATH=/usr/local/lib/python2.7/site-packages:$PYTHONPATH
「プラグインの調整」の項で書いたことは、実はbrewさんが既に注意してくれていたのですね… 完全に見逃していました。