コードバトン
Scheme コードバトンに参加しました
- 渡されたバトン http://gist.github.com/274246 from http://cadr.g.hatena.ne.jp/g000001/20100111/1263218782
- 渡したバトン http://gist.github.com/275132 to http://d.hatena.ne.jp/leque/20100114/p1
やったこと
このスクリプトは覚えているはずの単語との答え合わせのためのもののように見える
→ できるだけキーストロークが少ない方が嬉しいはず!
→ 何かキーを押すだけで答え表示、y/nを押した瞬間に次の問題が出てくれるようにしよう
ということで、cursesを使ってキー押下にすぐに反応するようにしました。
とりあえず動くというところまで持っていくまでで既に48時間をオーバーしていたので、
コードの整理を一切あとの人まかせにしてしまいました。
「人に優しい」が守られていなくて申し訳ないです。(lequeさんありがとうございます)
いろいろ
- unwind-protectが無いことに気付いたけど、すぐに書けませんでした。
- c-function で引数がvoidな関数をschemeに持ってくるにはどうすればいいのか?悩みました。
- libc.soだとライブラリがロードできなかったのでlibc.so.6と書きました。多分環境依存。
- LC_ALL の値も環境依存
- scheme文字列をC文字列に変換する関数を書くのが楽しかった! malloc!
- リソースの回収はOSという名のGCに任せる free free style で書かれています
自分で書いてないのに言うのもなんだけど、with-cursesみたいな制御構造を短いコードで書けるというのはlispの醍醐味の一つだと思う。
またやりたい! 楽しかった! 次回はもうちょっと時間とって、ちゃんとコードの整理までしてから次に渡したいと思います!
FreeBSD 7.1-RELEASE で kermit を使う
今日も20世紀の遺物をメンテナンスしているギーク(笑)の皆さん、こんにちは。
FreeBSD 7.1-RELEASE でシリアルモニタであるところのkermitを使おうとしたとこ、パーミッションの不備でそのままでは使えなかったので、設定方法をメモしておきます。
僕の場合は/dev/ttyd0がシリアルポートのデバイスだったんだけど、設定とか機械によっては違うかも。
まずttyデバイスの権限を調整する
# ls -l /dev/ttyd0 crw------- 1 root wheel 0, 43 Mar 27 18:13 /dev/ttyd0
こんな感じでrootしかアクセスできないから、chmodする。
kermitを使いたいユーザがwheelグループの場合:
sudo chmod 660 /dev/ttyd0
そうでない場合:
sudo chmod 666 /dev/ttyd0
ロックファイルのディレクトリにアクセスできるようにする
# ls -l /var/spool/ | grep 'lock$' drwxrwxr-x 2 uucp dialer 512 Mar 30 12:18 lock
という感じでdialerグループ権限でアクセスできるようになっているので、kermitを使いたいユーザのサブグループにdialerを加える。
おわり
ていうか _imp__ って何だろう
Scm_MakeU8VectorFromArraySharedならlibgauche-uvector.dllに入ってるんだけど……、_imp_Scm_MakeU8VectorFromArraySharedというのはどこにあるべきものなんだろう。
vport.dll に _imp__Scm_MakeU8VectorFromArrayShared が入っている←違った。使ってるだけ。
sdllib.cをコンパイルするときに、_imp__Scm_MakeU8VectorFromArrayShared が extern だよと宣言されてれば良い。。。んじゃないかな。
そういう問題じゃないみたい。。。そもそもlibgauche.dllに入ってるとはずなのに入ってないとかそういうことなのかなぁ。
cygwin な gosh + c-wrapper から mingw な SDL を使う
というわけで、sdl-config を使わずにCFLAGSとかLIBSを設定すればうまくいくかもしれないと思ってやってみた。
--- breakout_orig.scm 2009-02-20 15:43:06.406250000 +0900 +++ breakout.scm 2009-02-20 15:41:53.218750000 +0900 @@ -38,8 +38,8 @@ (use srfi-27) (c-load '("SDL.h" "SDL_mixer.h" "stdio.h" "stdlib.h" "sdl_helper.c") - :cppflags-cmd "sdl-config --cflags" - :libs-cmd "sdl-config --libs; echo '-lSDL_mixer'" + :cppflags "-I/usr/include/mingw/SDL" + :libs "-L/usr/lib/mingw -lmingw32 -lSDLmain -lSDL -lSDL_mixer" :import (list (lambda (header sym) (#/\/SDL\/.*\.h$/ header)) 'NULL
breakout.scm をこんな感じに直して cwcompile
gauche-package compile --verbose --cflags= --cppflags= -I/usr/include/mingw/SDL --ldflags= --libs= -L/usr/lib/mingw -lmingw32 -lSDLmain -lSDL -lSDL_mixer sdllib sdllib.stub '/usr/local/lib/gauche/0.8.14/i686-pc-cygwin/gauche-config' --fixup-extension 'sdllib' gcc -std=gnu99 -c -I/usr/include/mingw/SDL -I/usr/local/lib/gauche/0.8.14/include -o 'sdllib_head.o' 'sdllib_head.c' '/usr/local/lib/gauche/0.8.14/i686-pc-cygwin/gosh' genstub sdllib.stub gcc -std=gnu99 -c -I/usr/include/mingw/SDL -I/usr/local/lib/gauche/0.8.14/include -o 'sdllib.o' 'sdllib.c' gcc -std=gnu99 -c -I/usr/include/mingw/SDL -I/usr/local/lib/gauche/0.8.14/include -o 'sdllib_tail.o' 'sdllib_tail.c' gcc -std=gnu99 -L/usr/local/lib/gauche/0.8.14/i686-pc-cygwin -Wl,--export-all-symbols -Wl,--enable-auto-import -shared -o sdllib.dll 'sdllib_head.o' 'sdllib.o' 'sdllib_tail.o' -lgauche -lm -lpthread -L/usr/lib/mingw -lmingw32 -lSDLmain -lSDL -lSDL_mixer sdllib.o:sdllib.c:(.text+0x1a8): undefined reference to `__imp__Scm_MakeU8VectorFromArrayShared' collect2: ld returned 1 exit status *** ERROR: command execution failed: gcc -std=gnu99 -L/usr/local/lib/gauche/0.8.14/i686-pc-cygwin -Wl,--export-all-symbols -Wl,--enable-auto-import -shared -o sdllib.dll 'sdllib_head.o' 'sdllib.o' 'sdllib_tail.o' -lgauche -lm -lpthread -L/usr/lib/mingw -lmingw32 -lSDLmain -lSDL -lSDL_mixer Stack Trace: _______________________________________ 0 args 1 (usage) At line 101 of "(input string port)"
_imp__Scm_MakeU8VectorFromArrayShared があればうまくいきそうな。
mingwのSDLをcygwinから使う
特に問題なくできるみたいだ。
こういうファイルを用意して
#include <stdio.h> #include <SDL.h> int main(int ac, char** av) { if (SDL_Init(SDL_INIT_VIDEO) != 0) { fprintf(stderr, "can't init SDL\n"); } if (!SDL_SetVideoMode(640, 480, 32, SDL_ANYFORMAT)) { fprintf(stderr, "can't set video mode\n"); } SDL_Quit(); return 0; }
こうする
gcc -c cygwinsample.c -I/usr/include/mingw/SDL gcc -o cygwinsample cygwinsample.o -L/usr/lib/mingw -lmingw32 -lSDLmain -lSDL
実行すると一瞬画面がでてるからたぶんうまくいってる。
cygcheck の結果がこれ
.\cygwinsample.exe C:\cygwin\bin\cygwin1.dll C:\WINDOWS\system32\ADVAPI32.DLL C:\WINDOWS\system32\KERNEL32.dll C:\WINDOWS\system32\ntdll.dll C:\WINDOWS\system32\RPCRT4.dll C:\WINDOWS\system32\Secur32.dll C:\cygwin\lib\bin\SDL.dll C:\WINDOWS\system32\msvcrt.dll C:\WINDOWS\system32\GDI32.dll C:\WINDOWS\system32\USER32.dll C:\WINDOWS\system32\WINMM.DLL
というわけで、
負け
負けた。