一歩進んだ Rexx

Classic REXX (REstructured eXtended eXecutor)
File #03

SIKAKU -- '99.2.15

SIKAKU ・・ 最近やってる映画ではない。(←?)
それに 〆(^^) は映画はあまり見ないので, 最近なのかどうか知らないんだけど (^^;

これはコマンドラインなプログラムに使ったりする。実はこれレギュラー, つまり一軍(?)。 その中にあって一度も使ったことがない(あ, 公開ソフトウェアでの話ね)とゆーめずらしいもの。

って ♪話が飛ぶ飛ぶ家もとぶ〜

box: procedure expose Cols
parse arg r, c, h, w
/* Rc = RxCls(16, r, c, h +r -1, w +c -1) */
r = r +1; c = c +1;
home = '1b'x'['r';'c'H'
hbar = copies('06'x, w -2)
vbar = '08 1b'x'[B'copies('05 08 1b'x'[B', h -2)
if c +w <= Cols
   then vbarR = vbar
   else vbarR = '1b'x'['Cols -1'C'copies('05 1b'x'['Cols -1'C', h -2)
res = home vbar''home'01'x''hbar'02'x''vbarR'1b'x'['w -1'D' ||'03'x''hbar'04'x
call charout , res
return

えっとー, 呼び出し方は〜,

do i = 0 to 18
   call box i, i, Rows -i*2 -1, Cols -i*2
end
みたいな〜。
で, これ, 右端ぎりぎりでも表示できるってゆー結構すぐれもの。 まぁ最下行ではいくらなんでも無理ってもんだけどね。にょほほ。

Rexx で拘束下, じゃなくって 高速化を目指すってのはアレなのかもしんないんだけど, まぁ, それなりに早いよっ, これっ。(^-^)

忘れ物があった。

parse source OS .
if OS == 'OS/2' then do
   call RxFuncAdd 'SysLoadFuncs', 'rexxutil', 'SysLoadFuncs'
   call SysLoadFuncs
end

select
   when OS == 'DOS'  then parse value RxScrSize() with Rows Cols
   when OS == 'OS/2' then parse value SysTextScreenSize() with Rows Cols
otherwise
   say 'OS='OS
   exit
end

これ, 初期化処理。OS/2 でも DOSでも, どっちでもまかせてちょ なもの。


オプション引数の取得 -- '99.1.5

いや〜, いきなりでアレだけど, 一発目からいきなし Rexxをば・・。

これは引数からオプションを取得するもの(あれ?変だな)。C言語でゆー getopt() とか。 バリエーションがいっぱいあるんだけど, 基本的なヤツでいってみよー (って (^^;;)。

(↓)プログラムの最初の方を, こんな風にしておく。Argsは書替えられて戻るってな訳。

parse arg Args
call Opts
parse var Args FName .   /* 通常の引数 */

これが, その処理。まぁ, これってプログラムで違うかんねぇ。 このサンプルじゃ 3つ分アレしているけど, ここんとこを変更すべしって感じかな。 そして, 変更したら忘れずに説明文の部分を合わせねばなるまいっっ。

Opts:
do i = words(Args) to 1 by -1
   if pos(left(word(Args, i), 1), '-/') == 0 then iterate
   parse value word(Args, i) with +1 Opt'='Val
   Args = delword(Args, i, 1)
   Opt = translate(Opt)
   select
      when abbrev('ASCII', Opt) then fMode = 'Ascii'
      when abbrev('BINARY', Opt) then fMode = 'Binary'
      when abbrev('OUTFILE', Opt) then OutFile = Val
   otherwise
      say; say 'Options:';
      say '   -Ascii' '9'x'; Ascii mode'
      say '   -Binary' '9'x'; Binary mode'
      say '9'x'-OutFile=FILE ... 出力ファイル名'
      say
      exit
   end
end
if symbol('fMode') == 'LIT' then fMode = 'Default'
return

return 直前の処理は, 指定がなかった場合の処理 (のようなもの)。

特徴

ちょっち, 〆(^^) 風邪ひいて, 熱出して, ホッカホカ状態だったので, 変なのがあるかもしれない。あぁ, もう平熱くらいなんだけど, その後遺症とゆーか (←何だソレ)


16進dump, あるいは 2Byte文字 -- '98.11.27

今回, 軽目に・・とか思ったらばガニ, S-JISの説明が入りそうだにゃー。 まあ, そんな事は後回しにしておいてぇ (^^;
今んとこ, ここで紹介するのは 2つのバリエーションのものがあるとゆってもいいだろう。

Dump: procedure expose ctl
   parse arg val, ln, addr
   if ln = '' then ln = length(val)
   if addr = '' then addr = 0
   sz = 16   /* const */

   fmt = '01 23 45 67-89 ab cd ef-gh ij kl mn-op qr st uv'
   str = xrange(0, 9)xrange('a', 'v')
   do i = 1 to ln by sz
      if ln -i +1 < sz then sz = ln //sz
      ch = substr(val, i, sz)
      txt = d2x(addr, 8)'  'translate(fmt, c2x(ch), str)
      if \DBValidate(ch) then ch = ch ||substr(val, i +sz, 1)
      say txt ';' translate(ch,, ctl, '.')
      addr = addr +sz
   end
return ''

(↑)これは 小物ソフトの Xdumpでも使っているヤツ。
〆(^^) は (↓)こっちもよく使っている。

Dump: procedure expose ctl
   parse arg val, ln, addr
   if ln = '' then ln = length(val)
   if addr = '' then addr = 0
   sz = 16   /* const */

   do i = 1 to ln by sz
      if ln -i +1 < sz then sz = ln //sz
      ch = substr(val, i, sz)
      hx = c2x(ch)
      txt = d2x(addr, 8)' '
      do n = 1 by 2 for 16
         txt = txt substr(hx, n, 2)
      end
      if \DBValidate(ch) then ch = ch ||substr(val, i +sz, 1)
      say txt ';' translate(ch,, ctl, '.')
      addr = addr +sz
   end
return ''

呼び出すのには Dump(data)とかする。上の二つはびみょーに表示が異なる。
っと, その前にプログラム先頭に ctl = xrange('fd'x, '1f'x)がいる。 これ忘れたら表示が変になる。制御文字の範囲を指定する global変数ってゆーわーけ。 (←その表現であってんのか?)

この Dumpの特長は何といってもアレだ。(当然という気がしないでもないが)漢字が表示できること。 (←これを特長とゆってしまえることがすごい事なのかも知れない)
2Byte文字コードとゆーのは, それはそれは大変で, どっか 1Byte取ってきただけでは, それが 2Byteコードの一部なのか 1Byteコードなのかが分からないこと。 まだ EUCならば 2Byteコードの一部なのかどうかぐらいは分かるけど・・。 このため 文字列として適当なのかを調べるためには先頭から一つ一つ調べるか, 一つずつ判明するまで前に戻るかってゆーのが必要。(←なんか脱線してきたぞ)

え〜と。これのバヤイ。DBValidate()で判定している。まあ, 取っ手も便利 (←違うぞ, って前にも使ったぞ)
もし, 文字列が異様なら(16Byte目と17Byte目に全角がまたがっているようなら) 17Byte目をくっつけた 文字列にしてしまう。ってーことをしているわーけ。

うじゃ((C)竹本泉) (^^)/~


RxSock での Email送信 part II (2) -- '98.11.24

さて, 今回ので Emailは本当に完結 (の予定 (^^;)。

ここだけの話, 前回から 10日も経ってしまったのは, 実はヘッダーに漢字が入った時どうすればよいか 知らなかったりするのが主な訳だったりしちゃったり…。ちょっとねー, 本文だったら JISコードにすればいいのは分かるけど ヘッダーで漢字を扱ったのは今回初めてだったんでねー, それ知らずについ使って後で困ったりする。わはははははは, 大笑いー。 まあ墓穴を掘るってゆーの?, こーゆーの。

プログラムを作るための, それぞれのパーツと その順番はゆったからもういいとして (^^;;
漢字を扱う時の注意点。え〜と, つまり, そのまま前回までの通りにするとヘッダーに全角含むんで失敗しちゃうとゆーアレ。(送れる事は送れるんだけどもね)
先に bodyから。このプログラムではファイルを読み込みながら送信している。 最初っから漢字が入っている事が分かっていれば, RxJisToJis() を使うなどして JISに変換する。 そして次の項目をヘッダーとして追加する。(From:, To:, Subject: を使っているけど, そこいら辺にでも)

Content-Type: text/plain; charset="ISO-2022-JP"
Content-Transfer-Encoding: 7bit
もし, ファイルを読み込んでしまわないとわかんない〜 とかゆーんなら, まず読み込んで調べた後, 送信する。 例えば次のような感じで, flagが 1なら上のようなヘッダーを付ける。 (その時は送信も Rc = SockSend(sk, txt''nl)ではなくて Rc = SockSend(sk, RxJisToJis(txt)nl) )
flag = 0
do i = 1 while lines(FName) > 0
   body.i = lineIn(FName)
   if verify(body.i, xrange('80'x, ), 'M') > 0 then flag = 1
end
Rc = stream(FName, 'c', 'Close')
body.0 = i -1

つぎは ヘッダーについて。ヘッダーに漢字が入っていない場合はそのままでよいが, 漢字が入っている場合は, MIME で送信する場合と, そうでない場合とがある。うへー, 大変。
MIMEでない, とゆー場合は, お察しの通り JIS変換するだけ。 つまり Rc = SndMesg(sk, 'Subject:' m._subject nl)ではなく Rc = SndMesg(sk, RxJisToJis('Subject:' m._subject)nl)とか。 あるいは, SndMesg()側で行ってもよい。

では, MIMEで送信するとは いったいどうするのか。それは JIS変換した後さらに Base64エンコードする。ひえ〜。(←ちょっとうるさいかも)
単純に Base64エンコードすると 訳わか状態になるので, 該当する部分だけを変換し印を付ける。 ... 項目名の Subject: とかまでエンコードしたりしないよーに (通信相手は展開してくれないと思うぞ)

txt = '=?ISO-2022-JP?B?'RxJisToBase64(txt)'?='
(↑)なんか化けてるように見えないこともない …

こーゆーのんで, 参考になるのは (J_Pocketの) RxJisの MIMESEND.CMD。上に書いた処理内容を書くのにも参考に致しました。はい。
それにしても MIMESEND.CMDって複雑そう。なじぇか。それは 送り先によって MIMEを使う/使わないを指定できるようになっていて, その送り先ってゆーのを, ヘッダーを解析しながら調べていて, さらにヘッダーのたたみこみを処理しているから。 (←この文章でよけー難しくしたりして)

しかし, このプログラム 役に立つのだろーか。だれにも関係のないものだったりしたら・・・
『苦労かけるねぇ』『それは言わない約束よ』 (←何が言いたいんだか)


RxSock での Email送信 part II (1) -- '98.11.15

あう〜, 大失敗。(T_T

今回は E-mail送信の補足, というか組み立てというか ... まず先頭に

/* Rexx での E-mail送信プログラム    */
/* yy.mm.dd create by 名無しのごんべ */
options 'ETmode'
True = 1; False = 0;

MAX_RECVLEN = 1024
parse arg MTAaddr sendfile

このプログラムを起動する時に, 引数に smtpサーバのホスト名と 送信したいファイル名を指定する。 smtpサーバのホスト名は, 毎回指定しなくっても どこぞに覚えていてもいいんだけどね (^^

この後に, 一回目掲載分(リスト1-x)と 二回目掲載分(リスト2-x)がくる。 メインの部分(リスト2-3)は, この中の一番最後に持ってくる。 それから リスト1-1リスト1-2での中身(?)の順番はこんな感じ(↓)。そのほかは適当。そしてこれらの後ろに三回目掲載分(リスト 3-x)がくる。

  1. RxSock 外部関数パッケージの登録
  2. 名前の解決
  3. 接続

それから fromの idと toの idは正しく指定すること。できれば domainも正確な方がよい。あ, こういうところを どっかのデータベースにでも覚えておくといいカモ〜。

というところで, 失敗の部分はまた今度(^o^)/~~


Copyright (C) 1998-2004 Rexx使いの織華
email: ori@drive.co.jp