Just another Ruby porter,

〜2002年5月上旬〜


<Prev(,) | Next(.)> | Recent(/)>> | RDF

2002-05-01 (Wed)

[Ruby] -DNT -DIMPORT

embeddedなrubyを作る際に、ruby-talk MLでも-DNT -DIMPORTのつけ忘れが目立つ。 ということは逆にしたほうが使い易いと言える。 NTはdefines.hで

#if defined _MSC_VER || defined __MINGW32__ || defined __BORLANDC__
#define NT 1
#endif

とし、 defaultはIMPORTにしてRuby DLLをcompileするときは-DEXPORTにするのはどうだろう? 現在win32/win32.hでは

#undef EXTERN
#if defined(IMPORT)
#define EXTERN extern __declspec(dllimport)
#elif defined(EXPORT)
#define EXTERN extern __declspec(dllexport)
#endif

となっているが、実際EXPORTは使われていない。 def fileを作っているから必要ないというのもあるけど。 つまり

#undef EXTERN
#if defined(RUBY_EXPORT)
# define EXTERN extern __declspec(dllexport)
#else
# define EXTERN extern __declspec(dllimport)
#endif

とするわけだ。 単にIMPORTとかEXPORTだとぶつかる可能性が高すぎるので名前を変えた。 で、これをどうやって定義するかがいまいち困るわけだが、 やはり別の変数が必要だな。Makefile.inで

CFLAGS = @CFLAGS@ @RUBY_EXPORT@

みたいな。

実際試してみるとmissing/flock.c, ext/socket/getaddrinfo.cで破綻してしまった。 でも単にdefines.hをincludeすればいいだけか。 どちらもconfig.hはincludeしてるからここでNTを定義したほうが簡単かもしれない。 ext/socket/getnameinfo.cもそうか。 うーむ。ext/Win32API/Win32API.cはruby.hを最初にincludeしないとだめだ。 ということは拡張ライブラリを書き換えてもらう必要が出てくるわけか。 これはちょっと受け入れられないかもしれないな。

http-access2 E

更新。


2002-05-02 (Thu)

4月のspam

192通。韓国からは45通。今月は200通を越えるのか?昨日だけで既に8通来てるし。

[vim] UndoのUndo

Redo(CTRL-R)です。


2002-05-03 (Fri)

[Ruby] Ruby/Google 0.4.0

更新。

[Ruby] date2 3.0.1

更新。

[emacs] Undo

窓使いの憂鬱だと

window  PuTTY /putty.*\.exe:/ : Global
  key C-Slash => C-S-HyphenMinus

という手はあります。 default.mayuのTeraTermProのとこに書いてある通りですが。

[Ruby] AC_CHECK_DECLS

sys_nerrはAC_CHECK_DECLSで宣言が必要かどうかを調べるようになった。 でも$ac_includes_defaultには<errno.h>がない。 cygwinだと<errno.h>にsys_nerrの宣言があるのでちょっとまずい。 新しいldならauto-importがdefaultなので問題ない。 おそらく [ruby-talk:39482] は古いldを使ってるんじゃないかと思う。

ま、warningをなくす意味でも

AC_CHECK_DECLS([sys_nerr], [], [], [#include <errno.h>])

としてみた。が、これだと逆に$ac_includes_defaultがなくなるので最終的には

AC_CHECK_DECLS([sys_nerr], [], [], [$ac_includes_default
#include <errno.h>])

とした。

あ、たぶんwin32/config.h.inにも

#define HAVE_DECL_SYS_NERR 1

が必要だな。追加しとこ。


2002-05-04 (Sat)

[Cygwin] /proc

/proc/registryとかが使えるようになるらしい。 fhandler_proc.ccを見ると今はまだ/proc/versionと/proc/uptimeだけのようだ。

[Linux] diet-libc 0.17

更新。CHANGESを見ると

our i386 memchr,memcmp were broken for the count=0 case

ということで、 例の件 も直ってるようだ。 てゆかmemcmpもまずかったのか。

[Ruby] diet-libc対応

というわけで対応してみる。configure時のオプションは

--with-gcc='ccache diet gcc -nostdinc'

を追加。

io.c: In function `pipe_open':
io.c:1859: `NOFILE' undeclared (first use in this function)
io.c:1859: (Each undeclared identifier is reported only once
io.c:1859: for each function it appears in.)

NOFILEがないらしい。

/* EMX has sys/param.h, but.. */
#if defined(HAVE_SYS_PARAM_H) && !(defined(__EMX__) || defined(__HIUX_MPP__))
# include <sys/param.h>
#else
# define NOFILE 64
#endif

となっているが、<sys/param.h>にない場合が多いのだろう。 HIUXも最近新たに加わったようだ。BeOSとまとめて

#if defined(HAVE_SYS_PARAM_H) 
# include <sys/param.h>
#endif

#if !defined NOFILE
# if defined OPEN_MAX
#  define NOFILE OPEN_MAX
# else
#  define NOFILE 64
# endif
#endif

ぐらいがいいのかもしれない。

signal.c:291: redefinition of `sighandler_t'
/opt/diet/include/signal.h:87: `sighandler_t' previously declared here

これは困るね。configure.inに

AC_CHECK_TYPES([sighandler_t], [], [], [#include <signal.h>])

を入れて、signal.cのほうは

#if !defined HAVE_SIGHANDLER_T
typedef RETSIGTYPE (*sighandler_t)_((int));
#endif

としてみよう。

math.o(.text+0x4cc): undefined reference to `frexp'
numeric.o(.text+0x90d): undefined reference to `modf'
sprintf.o(.text+0xbb1): undefined reference to `frexp'
time.o(.text+0x385): undefined reference to `modf'

うーむ。これは結構面倒な気がする。


2002-05-05 (Sun)

Opera

Operaでfull screenモードにすると 見易いらしい。 とりあえずOpera 5 for Linuxをダウンロードしてみる。 なぜかSlide 30以降へ進めなくなる。しょうがないのでOpera 6のbeta版をダウンロード。 こっちは4.3MBもある。もちろんQTなど入れてないのでstatic版だ。 おお、いい感じ。最初からこっちダウンロードしとけばよかった。 5よりも圧倒的に速いし。

the fastest browser on earth!

と自信満々なメッセージを出すだけのことはある。

NFS mount

うーむ。そうだよね。すっかり忘れてた。 install時はxsystemしないのでlogを作る必要はない。 $installを見てopenするしないを判断すべきか?

sf.net

最近ダウンロードしようとするとミラーへ飛ばされて、ちと不便。

[Ruby] 付箋

単にbin/がないだけのようです。

% mkdir bin

でsetupもok。 あとsrc/をlib/にrenameしないとインストールされないとか、 そうしちゃうとpre-setup.rbがまずそうとか、 まだ不完全のよう。

[Ruby] frexp, modf

glibcやnewlibcやuClibcやDJGPPを見るとどれもCopyrightは同じで Sun Microsystemsらしい。というかどうもNetBSD経由らしい。 rcsidに$NetBSDの文字が。


2002-05-06 (Mon)

SOAP4R 1.4.4

更新。

Devel::Which 0.2.0

更新。

[zsh] サイズが0のファイル

% touch a b c
% ls *(L0)
a  b  c

ほんとzshって何でもありだよね。 誰かが書いてたけど、Rubyで使えるzsh globライブラリは欲しい気がする。

TV Bros.を見るとテレビ埼玉の18:00から「血」一文字だけの番組がある。 かなり不気味だ。見てみると「赤き血のイレブン」だった。懐しすぎ。


2002-05-07 (Tue)

SOAP4R 1.4.4.1

更新。

XML-RPC 1.7.10

更新。

Tmail 0.10.3

更新。

[Ruby] modf(3)

manを見ると

#include <math.h>
double modf(double x, double *iptr);

modf() 関数は、引数 x を整数部分と小数部分に分割する。この
と き、ふたつの値はともに x と同じ符号を持っている。整数部
分は iptr に保存される。

ということらしい。 一見

double modf(double x, double *iptr)
{
    *iptr = (int)x;
    return x - *iptr;
}

でよさそうな気がするが、 考えてみるとdoubleってのはintなんかよりかなり範囲が広いのでこれじゃだめなのだ。 たとえばtime.cでは

double f, d;

d = modf(RFLOAT(time)->value, &f);
t.tv_sec = (time_t)f;
if (f != t.tv_sec) {
    rb_raise(rb_eRangeError, "%f out of Time range", RFLOAT(time)->value);

というようにそれを積極的に利用している。

ちょっと変形して

double modf(double x, double *iptr)
{
    *iptr = x < 0.0 ? ceil(x) : floor(x);
    return x - *iptr;
}

でどう?-100のように負で小数部がないときに-0.0にはならないけど、ま、いっか。

XFree86 4.2.0

Cygwinのバイナリも用意されてるのか。


2002-05-08 (Wed)

[Ruby] frexp(3)

またman frexpを見ていろいろ考える。

#include <math.h>
double frexp(double x, int *exp);

説明
  frexp()関数は浮動小数点実数 x を正規化分数と
  exp に保存される指数に分解する。
返り値
  frexp()  関数は正規化分数を返す。引数 x がゼロでないなら、
  この正規化分数は x に2のべき乗を乗じた も の で あ り、 常
  に1/2から1の範囲となる(ただし1自体は含まれない)。 x がゼロ
  の場合、正規化分数はゼロになり exp にはゼロが保存される。

要するにlog2()があれば簡単な話なんだが、 そんな関数はないので、log(x)をlog(2.0)で割ることで代用。 こんな感じか?

#if !defined M_LN2
#define M_LN2 0.69314718055994530942
#endif

double frexp(double x, int *exp)
{
    double sign = 1.0;

    if (x == 0.0) {
        *exp = 0;
        return 0.0;
    } else if (x < 0.0) {
        sign = -1.0;
        x = -x;
    }
    *exp = log(x) / M_LN2 + 1;
    return sign * x / (2 << (*exp - 1));
}

うーむ。shiftしちゃだめだ。overflowする。 2のべき乗だからpowかldexpを使えばいいのか。 pow.Sとldexp.Sを比較するとldexpのほうが圧倒的に速そうな気がする。 それと、xがちょうど2のべき乗のときに*expが1.0になってしまうのもまずい。 というわけで

    double f;
    ...
    f = ldexp(1.0, *exp);
    if (x == f) {
        (*exp)++;
        f *= 2.0;
    }
    return sign * x / f;

でどうだろう?

明日にはminirubyができそうだ。

iconv 0.5

更新。


2002-05-09 (Thu)

[Ruby] diet libc版miniruby

missing/{modf,frexp}.cを作って、 modfとfrexpをconfigure.inのAC_REPLACE_FUNCSに追加。 configureし直して、とりあえずmake minirubyを実行。 link時にsprintfを使うなとかstdioを使うと7KB余分に消費するぞとか例の警告が出るが、 これでminirubyはできた。

ここで一度testしてみよう。

% ln -s miniruby ruby
% make test
sample/test.rb:1025:\
  in `sleep': Invalid argument - "sleep" (Errno::EINVAL)
        from sample/test.rb:1025
test failed

流石に一度ではうまくいかないようだ。エラーになったのは

sleep 0.1

で、これは 一昨日書いたところ が非常に怪しい。 gdbでbreakして何を返しているか見てみると全然でたらめな値になってる。 なぜ?しばらく考えてmodf(3)の宣言がないからintを返しているのが原因と気づく。 そりゃそうだよね。modfがないから作ったわけだし。 ってことは他にもあるんじゃないかと思ってチェックしてみると、 hypot, acosh(asinh, atanh)がまずい。 なにしろLinuxとか使ってると最初からすべてあるという状態だからなかなか気づかない。 これでmake testも通った。

frexpのほうはMath.frexpでRubyから呼べるので試してみる。

% ./miniruby -e 'p Math.frexp 10'
[2.5, 4]
% ruby -e 'p Math.frexp 10' 
[0.625, 4]

だめじゃん。うーむ。そうか、diet libcの<math.h>にはldexp(3)の宣言がない。 不完全だなあ。#ifdef __dietlibc__しないとだめだ。

% ./miniruby -e 'p Math.frexp 10'
[0.625, 4]

よさそう。

% ./miniruby -e 'p Math.frexp -10'
[-.625, 4]

printf系は0を省略するのか。これは問題にならないよね?

% ruby -e 'p -.1'
-0.1

なので、evalもできるから大丈夫だろう。

明日は拡張ライブラリだ。

inetd.co.jp

なんかよさそうなので、とりあえず1年間で契約してみた。 さっそくCVSでRuby 1.7.2を取ってきてmake all testした。 その前にautoconf 2.53をインストールしたり。


2002-05-10 (Fri)

[Ruby] ruby-core ML

動き始めた。

[Ruby] missing.h

missing.hにプロトタイプ宣言を入れることになった。 でもvsnprintfとか結構面倒だね。 <stdarg.h>をincludeしなきゃいけないとか。

[Ruby] _snprintf, _vsnprintf

msvcrt.dllでは_snprintf, _vsnprintfというシンボルだということに、 今更ながら気づく。 win32/win32.hで

#define vsnprintf  _vsnprintf
#define snprintf   _snprintf

としているのでMinGWでは無駄にvsnprintf.oがリンクされてしまう。 MinGWのときはそれを削除したいが、 LIBOBJSなのでconfigure.inの中では手を出すことはできない。 しかたないのでcygwin/GNUmakefile.inで対処しよう。

ARCH=@arch@

ifeq ($(ARCH),i386-mingw32)
  MISSING := $(filter-out vsnprintf.o,$(MISSING))
endif

<Prev(,) | Next(.)> | Recent(/)>> | RDF


WWW を検索 jarp.does.notwork.org を検索

わたなべひろふみ
Key fingerprint = C456 1350 085F A320 C6C8 8A36 0F15 9B2E EB12 3885
Valid HTML 4.01!