PostScript のバイナリ化スクリプトを改良
id:yshl:20070722:1185087141 の続き。
浮動小数点数にも対応してみたが、バイナリ化するべきかそのままにすべきかの判定がまだ甘い。あと、前の奴だと文字列が 256 文字以上でエラーになるのを 65535 文字まで OK にしたが、こちらもバイナリ化の判定が甘い。
以下ソース
#!/bin/sh exec gs -q -dNODISPLAY -dBATCH -d#!='{2{currentfile 256 string readline{pop}if}repeat}' -- $0 "$@" ARGUMENTS length 0 eq{ (%stdin) }{ ARGUMENTS 0 get }ifelse (r)file /infile exch def /tobinmethods 9 dict def tobinmethods begin /SystemNames where{ pop SystemNames 0 226 getinterval }{ [ 0 1 225{ (\222 )dup 1 4 3 roll put token{exch pop}if }for ] }ifelse /list exch def /bindict list length 6 add dict def 0 1 list length 1 sub{ /i exch def bindict list i get 2 string dup 0 146 put dup 1 i put put }for bindict /true (\215\1) put bindict /false (\215\0) put [([)(])(<<)(>>)]{ bindict exch dup cvn exch put }forall %bindict{exch =only ==}forall /alnum? false def /inttobin{ 2 dict begin /n exch def n -128 ge n 128 lt and{ 2 string dup 0 136 put }{ n -32768 ge n 32768 lt and{ 3 string dup 0 135 put }{ 5 string dup 0 133 put }ifelse }ifelse /buf exch def 1 1 buf length 1 sub{ buf exch n 1 index 1 sub -8 mul bitshift 255 and put }for buf end }def /floattobin{ 5 dict begin dup 0. eq{ (\214\0\0\0\0) }{ dup 0 gt{0}{neg 1}ifelse /sign exch def dup ln 2 ln div floor cvi 2 copy 2 exch 1 add exp ge{1 add}if dup -127 le{ /expon 0 def pop -126 }{ /expon 1 index 127 add def }ifelse 2 exch exp div 128 mul dup cvi dup /frac1 exch 127 and def sub 256 mul dup cvi dup /frac2 exch def sub 256 mul dup cvi dup /frac3 exch def sub pop (\214 ) dup 1 frac3 put dup 2 frac2 put dup 3 frac1 expon 1 and 7 bitshift or put dup 4 expon -1 bitshift sign 7 bitshift or put }ifelse end }def /stringtype{ tok length 256 lt{ (\216 )dup 1 tok length put print }{ (\217 )dup 1 tok length 256 idiv put dup 2 tok length 256 mod put print }ifelse tok print /alnum? false def }def /integertype{ tok 10 lt tok 0 ge and alnum? not and{ tok =only /alnum? true def }{ tok inttobin print /alnum? false def }ifelse }def /realtype{ tok 20 string cvs length 5 gt{ tok floattobin print /alnum? false def }{ alnum?{( )print}if tok ==only /alnum? true def }ifelse }def /nametype{ /tok load xcheck{ bindict /tok load known{ bindict /tok load get print /alnum? false def }{ alnum?{( )print}if /tok load ==only /alnum? true def }ifelse }{ /tok load ==only /alnum? true def }ifelse }def /arraytype{ ({)print /alnum? false def /tok load{tokentobin}forall (})print /alnum? false def }def end %quit /tokentobin{ tobinmethods begin /tok exch def /tok load type exec end }def { infile token not{exit}if tokentobin %(%stdout)(w)file flush }loop