コードバトン

Scheme コードバトンに参加しました

やったこと

このスクリプトは覚えているはずの単語との答え合わせのためのもののように見える
→ できるだけキーストロークが少ない方が嬉しいはず!
→ 何かキーを押すだけで答え表示、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を加える。

おわり

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

というわけで、

  • -I/usr/include/mingw しない
  • -Dmain=SDL_main しない
  • -mno-cygwin -mwindows しない

コンパイルとリンクをすればmingwなDLL自体はcygwinなexeからよろしく使えそうな気配。