# HG changeset patch # User gongo # Date 1194687247 -32400 # Node ID 5dc0243acd99743db446325882f3f07920b7fe85 # Parent 3a876dbe08416956d93355f9de041bcee369d850 add test routine (translate.el) diff -r 3a876dbe0841 -r 5dc0243acd99 ChangeLog --- a/ChangeLog Sat Nov 10 17:22:15 2007 +0900 +++ b/ChangeLog Sat Nov 10 18:34:07 2007 +0900 @@ -1,5 +1,14 @@ 2007-11-10 Wataru MIYAGUNI + * add: translate.el + translate のテストルーチン。使い方は + + M-x load-file RET [translate.el] + M-x translate-test + + ってやると、*Message* バッファに、 + translateの結果が出力されます。きっと。 + * redit-client-sm.el:unpack-int < (setq num (* byte 4)) < (string-to-char (substring pkt num (+ num 1))))) diff -r 3a876dbe0841 -r 5dc0243acd99 translate.el --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/translate.el Sat Nov 10 18:34:07 2007 +0900 @@ -0,0 +1,171 @@ +(eval-when-compile (require 'cl)) + +(defstruct Queue (front nil) (rear nil)) +(setq lc-queue (make-Queue)) +(setq rc-queue (make-Queue)) + +;; ランダムで i,r,d を出力するための配列 +;; 決めうちでごめんなさい +(setq cmd-array [6 9 13]) + +;; return 0 or 1 or 2 +;; cmd-array で使います。 +(defun random3 () + (setq rd (random)) + (setq rd (if (< rd 0) (* rd -1) rd )) + (setq rd (% rd 3))) + +;; @param queue REPcommand queue +;; @param item REPcommand +(defun enqueue (queue item) + (let ((new-cell (list item))) + (if (Queue-front queue) + ;; 最終セルを書き換える + (setf (cdr (Queue-rear queue)) new-cell) + ;; キューは空の状態 + (setf (Queue-front queue) new-cell)) + (setf (Queue-rear queue) new-cell))) + +;; @param queue REPcommand queue +;; @return REPcommand +(defun dequeue (queue) + (if (Queue-front queue) + (prog1 + (pop (Queue-front queue)) + (unless (Queue-front queue) + ;; queue become empty + (setf (Queue-rear queue) nil))))) + +(defun redit-pack-int-loop (num count) + (if (> count 0) + (concat + (redit-pack-int-loop (/ num 256) (- count 1)) + (char-to-string (% num 256))))) + +(defun redit-pack-int (num) + (redit-pack-int-loop num 4)) + +(defun redit-pack (cmd sid eid seq lno siz) + (concat + (redit-pack-int cmd) (redit-pack-int sid) (redit-pack-int eid) + (redit-pack-int seq) (redit-pack-int lno) (redit-pack-int siz))) + + +(defun unpack-int (pkt byte) + (let (num) + (setq num (* byte 4)) + (string-to-char (substring pkt (- num 1) num)))) + +(defun rep-get-command-from-pkt (pkt) + (unpack-int pkt 1)) +(defun rep-get-line-number-from-pkt (pkt) + (unpack-int pkt 5)) + +(defvar redit-write-command "6") ;; insert +(defvar redit-delete-line-command "9") +(defvar redit-replace-command "13") +(defvar redit-nop-command "15") + + + +;; @param rcmd REPcommand queue of Remote Host +;; @param lcmd REPcommand queue of Local Host +;; +;; 比較時に行番号が重なったときの処理は以下の表。 +;; なるべくテキストが残るようにしている。 +;; 0 -- なにもしない +;; +1 -- 行番号を +1 +;; INS -- コマンド id を 'REPCMD_INSERT' にする。 +;; NOP -- コマンドをNOP(何もしない)にする。 +;; ?* -- TOKENがMasterを通っていなければ +;; REMOTE +;; | i | r | d +;; ---|------------------ +;; U i | +1* | +1 | +1 +;; S ---|------------------ +;; E r | 0 | NOP*| NOP +;; R ---|------------------ +;; d | 0 | INS | NOP +;; +;; @exec 今は上の表通りに message で出力。 +;; +(defun translate (rcmd lcmd) + (let + ((rc (rep-get-command-from-pkt rcmd)) + (lc (rep-get-command-from-pkt lcmd)) + (rlno (rep-get-line-number-from-pkt rcmd)) + (llno (rep-get-line-number-from-pkt lcmd))) + + (if (= rlno llno) + (progn + (cond ((= lc (string-to-number redit-write-command)) + ;; local REPcommand is insert + (cond ((= rc (string-to-number redit-write-command)) + ;; remote REPcommand is insert + (message "local=i, remote=i lineno++ *") + ) + ((= rc (string-to-number redit-replace-command)) + ;; remote REPcommand is replace + (message "local=i, remote=r lineno++") + ) + ((= rc (string-to-number redit-delete-line-command)) + ;; remote REPcommand is delete + (message "local=i, remote=d lineno++") + )) + ) + ((= lc (string-to-number redit-replace-command)) + ;; local REPcommand is replace + (cond ((= rc (string-to-number redit-write-command)) + ;; remote REPcommand is insert + (message "local=r, remote=i 0") + ) + ((= rc (string-to-number redit-replace-command)) + ;; remote REPcommand is replace + (message "local=r, remote=r cmd = NOP *") + ) + ((= rc (string-to-number redit-delete-line-command)) + ;; remote REPcommand is delete + (message "local=r, remote=d cmd = NOP") + )) + ) + ((= lc (string-to-number redit-delete-line-command)) + ;; local REPcommand is delete + (cond ((= rc (string-to-number redit-write-command)) + ;; remote REPcommand is insert + (message "local=d, remote=i 0") + ) + ((= rc (string-to-number redit-replace-command)) + ;; remote REPcommand is replace + (message "local=d, remote=r cmd = insert") + ) + ((= rc (string-to-number redit-delete-line-command)) + ;; remote REPcommand is delete + (message "local=d, remote=d cmd = nop") + )) + )) + )) + )) + +;; rcmd[0] <> lcmd[0] +;; rcmd[1] <> lcmd[1] +;; rcmd[2] <> lcmd[2] +;; .... +;; って感じで、queue の command を translate するテストルーチン +(defun translate-test () + (interactive) + (setq num 0) + (while (< num 30) + (message (number-to-string (aref cmd-array (random3)))) + + (setq Rcmd (concat + (redit-pack + (aref cmd-array (random3)) 0 0 0 31 0))) + (setq Lcmd (concat + (redit-pack + (aref cmd-array (random3)) 0 0 0 31 0))) + (enqueue rc-queue Rcmd) + (enqueue lc-queue Lcmd) + (setq num (+ num 1))) + (while (> num 0) + (translate (dequeue rc-queue) (dequeue lc-queue)) + (setq num (- num 1)))) \ No newline at end of file