10 December 2008

subversion クライアントのバージョン違いによるエラー

subversion のバージョン1.4と1.5では、作業コピーのフォーマットが異なります。1.5 -> 1.4 への操作はできますが、1.4 -> 1.5 はできません。たとえば、僕の場合はこういう状況でした。

  1. 普段はバージョン1.4* の環境で作業
  2. たまたま普段使わないマシンを使う
    • そのマシンのsvnのバージョンが1.5だった
  3. 普段の環境に戻り、作業を再開しようとすると、エラーがでた。
svn: このクライアントは、作業コピー '.' を扱うには古すぎます。もっと新しい Subversion クライアントをダウンロードしてください。

解決策

解決方法としては、

  • 普段使う環境のsvnのバージョンを1.5にあげる
  • 1.5 のフォーマットになってしまった作業コピーを、1.4のものへ変換する

のどちらかかと思います。

解決法としては前者の方がベターですが、ここでは後者の方法を紹介します。

change-svn-wc-format.pyで作業コピーのフォーマットを変換

change-svn-wc-format.py というパイソンのスクリプトで、とても簡単に変換できます。

change-svn-wc-format.py

上記サイトから change-svn-wc-format.py をダウンロードし、

$ python change-svn-wc-format 作業ディレクトリへのパス 戻したいバージョン(ここでは1.4)

とするだけです。

続・CとEusLisp間の、共有メモリでの通信

CとEusLisp間の、共有メモリでの通信 - フリーフォーム フリークアウト の続き。

EusLispでは、共有メモリはベクトルとして扱われます。ベクトルの各要素は、1バイトの整数です。例えばベクトルの10要素目は、共有メモリの10バイト目に相当します。このように1バイトごとに分かれているため、255以上の値を扱いたいときには工夫が必要なのかもしれません。

前回こう書きましたが、間違いでした。EusLispでの共有メモリは、"foreign-string"という形式で扱われています。つまりmap-file関数は、ファイルをメモリに配置(マップ)し、その結果としてforeign-stringを返します。

foreign-stringとは

foreign-stringは、EusLispのヒープ領域の外にある、バイトベクトルの一種です。長さと文字列本体への'アドレス'を持っています。(対して、普通の文字列は長さとバイト列を持っています)。よってforeign-stringには、length、aref、replace、subseq、copy-seqなどの関数でアクセスできますが、ほかの文字列操作関数には使えないものもあります。

EusLispには文字列型は存在せず、単に整数として扱われているので、共有メモリからarefで要素を取り出してprintすると、アスキーコードが表示されます。よって、たとえば共有メモリに数値を書きこみたいときなどは、string関数を用いて数値の文字列表現(アスキーコード)を得て、replaceなどで書き込むのが良さそうです。

sample

; 共有メモリの準備。shared-string1にバインド
(with-open-file (f "MapFile" :direction :output)
  (princ (make-string 64) f))
(setf shared-string1 (map-file "MapFile" :direction :io))

; 共有メモリに'1'を書き込む関数
(defun write-test ()
  (setf code (string 1))
  (replace shared-string1 code)
)

おさらい:ヒープ領域

ヒープ領域 - Wikipedia

  • プログラムで動的に確保可能なメモリ領域
  • データ構造でのヒープとは関係なし
  • 双方向リストで実現されている

OSとコンパイラのことは、きちんと勉強してみたいです。おもしろいし、普段のプログラミングに有用です。