gdbmgr - Dr.Chip 先生による gdb 統合プラグイン

http://mysite.verizon.net/astronaut/vim/#GDBMGR
ちょっとだけ試してみた。
vimgdb と違い、コンソールでも使える。
python or perl インターフェイスが必要。
コンパイルしといて

 export LD_LIBRARY_PATH="$HOME/.vim/gdbmgr/src:default"

起動

:GdbMgr progname

キーバインド

F6   ブレークポイントトグル
n    next
s    step
など。

コンパイルした共有オブジェクトに libcall() してそこから forkpty() して gdb を起動している。
現時点での完成度は、ごく小さなプログラムには使えそうだけど…という感じ。


TTYShare にアップしたらうまく表示されなかったので、ttyrecord データをここに置いとく。
http://www.k3.dion.ne.jp/~jod/gdbmgr.ttyrecord

screen−擬似端末の深遠なる黒魔術

man screen の exec の項に書いてあった ps ファイルを pdf 化。
screen の exec コマンドで使えるファイルディスクリプタつなぎかえの全パターンを示している。
http://www.k3.dion.ne.jp/~jod/fdpat.pdf


W はすでにスクリーン内で動いているプロセスの pty。
P は exec で新たに起動するプロセスの pty。
図の左側にキー入力と画面出力がある。
!!. や !!! を使えば expect が作れるし、!.. を使えば script が作れると言うわけだ。
.!. や .!! の input filter も何かできそうだが、それ以外はほとんど使い道が思いつかない。

つなぎかえは 3 * 3 * 3で 27 パターン。そのうち fd 1, 2 が :. と .: のとき結果は同じだから 6 パターン減って 21 パターン。


恥ずかしながら、私、本日まで screen を端末を切り替えるだけのレガシーアプリケーションだと思っていました。backtick さえ知りませんでした。デタッチの仕組みも考えたことなかった。これ作ったやつは天才だと思った。

しかし、詳解UNIXプログラミングの pty コマンドを見たときは感動したものだけど、これには何か邪悪なものを感じる。なるほど GNU だ。


もう一つ入っていた「Window to display data flow in Screen」。
http://www.k3.dion.ne.jp/~jod/window_to_display.pdf

ダブルディスパッチ

(2)ここで(しかたなく) @a と @b を attr で公開しましたが、
公開しないでこの eql? と同様なものは作れるでしょうか?

現状では普通にはできません.ちょっとひねれば

  def eql? other
    other.check_eq? @a, @b
  def
  def check_eq? a, b
    a == @a and b == @b
  end

こういうやりかた(まず自分のメソッドで絞り込みやデータの取り
出しを行い,残りは相手のメソッドに任せてしまうようなやりかた)
をダブルディスパッチと呼びます.オブジェクト指向では良く使わ
れるやり方なので覚えておくと便利でしょう.

http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/1659

NetBeans インターフェイス

netbeans.jax 翻訳完了。
http://www.kaoriya.net/vimdoc_j/vimdoc_ja-snapshot.tar.bz2

NetBeans インターフェイスって、別に NetBeans 専用じゃなくて、どんな IDE とでも統合できるようにするための汎用インターフェイスだったんだ…
メッセージは行指向のプレインテキストで送られるので、netcat などでも簡単に対話できる。
NetBeans サーバ役(Vim コントローラ)をするスクリプトを適当に書いてみた。

# -*- coding: utf-8 -*-
import socket
import os
import sys
import re

HOST = ''
PORT = 3219

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((HOST, PORT))
s.listen(1)
conn, addr = s.accept()
conn_f = conn.makefile()

print 'Connected by', addr

def sendToVim(bufID, name, arg=""):
    global sendsecno
    global conn_f
    sendsecno += 1
    message = "%s:%s%s %s" % (bufID, name, sendsecno, arg)
    conn_f.write(message + "\n")
    conn_f.flush()
    print "SEND [%s]\n" % message,

try:
    sendsecno = 0
    while True:
        line = conn_f.readline().rstrip("\r\n")
        print "%s" % (line)
        m = re.match('^(\d+):(\w+)=(\d+)(.*)', line)
        if m:
            # イベント受信
            bufID     = m.group(1)
            eventName = m.group(2)
            seqno     = m.group(3)
            arg       = m.group(4)
            #print "==========> bufID=[%s] eventName=[%s] secno=[%s]" % (m.group(1), m.group(2), m.group(3))
            if eventName == "fileOpened":
                filePath = arg.split()[0]
                print "filePath = [%s]" % filePath
                # bufID をセット
                sendToVim(1, "putBufferNumber!", filePath)
                # バッファの長さを取得
                sendToVim(1, "getLength/")
                # バッファの0バイト目に文字列挿入
                sendToVim(1, "insert/", '0 "Hello from NetBeans!"')
except socket.error:
    pass
finally:
    conn.close()

実行:
1. netbeans.py 起動

$ python netbeans.py

2. gvim 起動

.\gvim -u NONE -N -nb:localhost:3219:mypass

3. gvim 側で手動で vimrc を開く。
バッファに "Hello from NetBeans!" が挿入される。
キーボードから適当に挿入するとその都度イベントが送られる。

Connected by ('127.0.0.1', 2352)
AUTH mypass
0:version=0 "2.4"
0:startupDone=0
0:fileOpened=0 "C:\\ao\\dl\\vim72-kaoriya-w32j\\vimrc" T F
filePath = ["C:\\ao\\dl\\vim72-kaoriya-w32j\\vimrc"]
SEND [1:putBufferNumber!1 "C:\\ao\\dl\\vim72-kaoriya-w32j\\vimrc"]
SEND [1:getLength/2 ]
SEND [1:insert/3 0 "Hello from NetBeans!"]
2 9306
3
1:insert=3 21 "\n"
1:remove=3 21 0
1:insert=3 21 "m"
1:remove=3 21 1
1:insert=3 21 "me"
1:remove=3 21 2
1:insert=3 21 "m"
1:remove=3 21 1
1:insert=3 21 ""
1:remove=3 21 0
1:insert=3 21 "メ"
1:remove=3 21 2
1:insert=3 21 "メッ"
1:remove=3 21 4
1:insert=3 21 "メッセ"
1:remove=3 21 6
1:insert=3 21 "メッセー"
1:remove=3 21 8
1:insert=3 21 "メッセージ"
1:remove=3 21 10
1:insert=3 21 "メッセージは"
1:insert=3 34 ""
1:insert=3 34 "\n"
1:remove=3 21 13
1:remove=3 21 12
1:insert=3 21 "メッセージはU"
1:remove=3 21 13
1:insert=3 21 "メッセージはUT"
1:remove=3 21 14
1:insert=3 21 "メッセージはUTF"
1:remove=3 21 15
1:insert=3 21 "メッセージはUTF-"
1:remove=3 21 16
1:insert=3 21 "メッセージはUTF-8"
1:remove=3 21 17
1:insert=3 21 "メッセージはUTF-8で"

何か面白い使い方を考えたいけど、Vim 側でのコマンド実行をほとんど拾えないので、IDE との統合以外にはあまり使えないような気がする。

readline で閉じカッコを入力したとき対応するカッコへ飛ぶ

man readline には書いてないけど blink-matching-paren という変数があるらしい。
.inputrc に書いておけば python, irb, mzscheme なんでも、) を入力したとき、一瞬対応するカッコにカーソルが飛ぶようになる。

set blink-matching-paren on

partial write

対象が端末、ネットワーク、SVR4 のストリーム装置などの装置では、
write(2) は書き込み要求したバイト数より少ない値を返すことがある。
フロー制御などのためである。
(詳解UNIXプログラミング 12.8)

dual.py

def writeall(fd, data):
  while len(data) != 0:
    n = os.write(fd, data)
    data = buffer(data, n)

APUE 12.8 には同様の writen() 関数が書かれている。

Architectural Repair of Open Source Software

http://web.archive.org/web/20030406224753/http://plg.uwaterloo.ca/~migod/papers/iwpc00.pdf

研究として、LinuxVim 5.3 についてアーキテクチャの修正を行ったという話。
Vim の方について簡単にメモ。

概念的アーキテクチャ
設計上のアーキテクチャ
具体的アーキテクチャ
ソースコード上のアーキテクチャ
anomalies
具体的アーキテクチャと概念的アーキテクチャの不一致
Unexpected dependencies
概念的アークテクチャにあるが具体的アーキテクチャにはない依存関係。
Gratuitous dependencies
具体的アークテクチャにあるが概念的アーキテクチャにはない依存関係。
Forward architecture repair
概念的アーキテクチャに合うように具体的アーキテクチャを修正すること。
Kidnapping
モジュールなどを移動させる。
Splitting
モジュールなどを分割する。
Reverse architecture repair
具体的アーキテクチャに合うよう概念的アーキテクチャを修正すること。

やったこと

  • misc1.c と misc2.c に正規表現、文字列ユーティリティ、メモリユーティリティなど雑多なものがあった。
  • 正規表現関連を regexp.c に移動。
  • 文字列ユーティリティを vim stdlib.c に移動。
  • メモリユーティリティを memory.c に移動。
  • buffer.c に構文ハイライト関連の処理があるので、新たに Buffer というサブシステムを概念アーキテクチャに追加。
  • かかった時間は 80 person hour。