Newsgroups: fj.lang.tcl,fj.archives.answers
Subject: [comp.lang.tcl] Tcl Language Usage Questions And Answers
Distribution: fj
Followup-To: fj.lang.tcl
Reply-To: taguchi@aic.co.jp
Expires: Fri Apr 14 00:00:00 JST 1995
Keywords: FAQ tcl tclX

Archive-name: tcl-usage-QnA-j/part01
Version: 1.4-J1.0

Last modified: Fri Mar 24 13:51:17 1995

Posting-Frequency: monthly

訳者まえがき

これは,joe@morton.rain.com (Joe Moss) 氏によって管理される "FAQ: comp.lang.tcl Tcl Language Usage Questions And Answers" の 3月1日版の日本語訳です. 今回もオリジナルをalcatelアーカイブから取りましたので, ヘッダはありません.

この日本語訳に対するご意見・ご質問・誤りのご指摘などは,訳者まで. また,その他の詳細な情報については,tcl-faq-j/part00 を参照して下さい.


はじめに

本 FAQ ファイルは,Tcl プログラミング言語に関する, 共通的によく聞かれる質問を扱うことを目的としています. このような質問が本文章で整理されることにより, comp.lang.tcl の同じ投稿の繰り返しが減り, より情報的になることを期待します. また,本文書や他の FAQ によって, より多くの人々が Tcl や Tcl ベースのアプリケーションを より便利に使えるようになることも期待します.

このFAQは,Joe Moss (joe@morton.rain.com)により管理され, 毎月 comp.lang.tcl と news.answers に投稿され,また, ftp.aud.alcatel.com (198.64,191,10) の /tcl/docs ディレクトリや,World Wide Webページ http://route.psg.com/tcl.html からでも入手することができます.

本 FAQ は Tcl に関して扱うものであり, Tk についてのものではないことに注意して下さい. Tk ツールキットに関しては,Thomas J. Accardo (tja@cpu.com) から投稿されている FAQを参照するとよいでしょう (他のTclに関するFAQに関しては, 後述の質問「Tclに関する情報をもっと知りたいのですが」参照). しかしながら,必然的に情報がだぶる場合もあります. Tk ウィジェットの扱い方に関する最もよく聞かれる質問のいくつかは, Tcl インタプリタの動作自体に対する誤解に起因するものです. こういった問題は,今後もここで扱われます. また,Tcl の扱いの幾つかの例題では, Tkのウィジェットを実行する必要がある場合もあるでしょう.

Tk に依存しない拡張(拡張 Tcl や Expect など,ただし,TkX や expecTk, BLT は除く)の使い方に関する質問と回答もまた,ここで取り扱われます.

この文章のソースは,現在では HTML 形式で管理するようになりました. テキストバージョンに質問番号や質問目次, From や Subject 行を魔法の様に自動的に付加するために,2 つのスクリプト (もちろん,Tcl で書かれています)を通しています. WWW から参照できるバージョンは,変更がある度に更新されますが, ASCII テキストバージョンは月に1度,生成,投稿されるだけです.


質問目次:

一般情報:

  • Q1- Tclに関する情報をもっと知りたいのですが?
  • Q2- 私のマシン上で Tcl を動かすために必要な情報を得るには?
  • Q3- TclとCを組み合わせるには?
  • Q4- 欲しい機能全てを提供できるように,数々の拡張を組み合わせるには?
  • Q5- 動的ローディングって何ですか?
  • Q6- Tclがインストールしてない環境でも動作する, スタンドアローン・プログラムを作るには?
  • Q7- tclshがインストールされている場所に関係なく, スクリプトを動作させるには?
  • Q8- 何で<ほげほげ拡張>がデフォルトの配付に含まれてないの?
  • プログラミング関連の質問と回答:

  • Q9- 連想リストや属性リストを生成/使用するには?
  • Q10- Tclで乱数を発生させるには?
  • Q11- あるプロシージャから返される複数のパラメータを, 別のプロシージャに引数として渡すには?
  • Q12- 配列をプロシージャに渡すには?
  • Q13- 外部コマンドを実行して,その出力をパイプを通して読むには?
  • Q14- スクリプト中でプロシージャの定義を削除するには?
  • Q15- 7桁以上の倍精度の精度を得るには?
  • Q16- 非組み込み呼出の発生をトラップするには?
  • Q17- 環境変数の読み出しや設定を行うには?
  • Q18- 頭に0が付いた数字を扱うには?
  • Q19- コマンドライン引数を参照したいのですけど?
  • Q20- 例えばcase文中などに,コメントを書きたいのですが?
  • Q21- バイナリ・データの読み書きをするには?
  • Q22- シグナルをトラップするとか,その他のUnix固有の機能を使うには?
  • Q23- 間接指定をしたいのだけど.-- 何で$$varが動かないの?
  • Q24- クォートされた文字列を意図した通りに動かすには?
  • Q25- プロシージャ定義を複数のスクリプトで共有するには?
  • Q26- リストに挿入された要素を得るには?
  • Q27- ファイル識別子から非ブロック化入力を行うには?
  • Q28- デッドロックさせずにパイプで入出力するには?
  • Q29- 実行中のバージョンを知るには?
  • Q30- 配列名を入れた変数を使うには?
  • プラットホーム固有,あるいは移植性に関する質問:

  • Q31- AIXでTcl/Tkの共有ライブラリを構築するには?
  • Q32- HP-UXでTclをコンパイルできた人はいませんか?
  • Q33- VMSでTclをコンパイルできた人はいませんか?
  • Q34- SCO UnixでTclをコンパイルするには,どうしたらいいんでしょう?
  • Q35- tclTextを走らせると,formatやscanでエラーになるのは何故?
  • Q36- tclTextをIrix 4.0.1で走らせると一杯エラーが出るのは何故?
  • Q37- CrayでTclを問題なく走らせた人はいませんか?
  • Q38- Tcl 7.1/Tk 3.4をNeXTSTEP 3.1で走らせるには?
  • Q39- TclをNextにインストールするには?
  • Q40- Tk3.4をNEXTSTEP3.1にインストールするには?
  • Q41- Tcl/Tk本のドラフトを印刷できないのですけど.
  • Q42- SGI Indigo上でエラーが出るのはなぜ?
  • Q43- expectをSolaris2.3で構築するには?
  • Q44- SequentにTcl/Tkを移植するには?
  • Q45- AU/X 3.0でシンボルテーブルが一杯になるのを避けるには?
  • Q46- MS-DOSやMacOS,その他の非UnixマシンでTclをコンパイルするには?
  • Q47- QNXマシン上でTclをコンパイルするには?
  • Q48- Tclスクリプトを実行しようとすると "Command not found"というメッセージが出るのは何故?

  • 一般情報:

    From: Tcl Q&A
    Subject: Q1- Tclに関する情報をもっと知りたいのですが?

    ニュースグループcomp.lang.tclは,Tcl言語とそれをベースとするパッケージに 関して議論を行うために存在します. オンライン版や印刷された様々な材料に関する情報や参照先をまとめた,Tclの 数々のFAQ文章が,ftp.aud.alcatel.comの/tcl/docsディレクトリから入手できます. これらはまた,WWWを使って, http://www.cis.ohio-state.edu/hypertext/faq/usenet/tcl-faq/top.html からもアクセスできます.

    Webで情報サーフィンできるなら,以下の2つがスタート点としてよいでしょう. それは, http://www.sco.com/IXI/of_interest/tcl/Tcl.htmlと, http://web.cs.ualberta.ca/%7Ewade/HyperTcl/です.

    もちろん,配付品のソースコードそれ自体にも, 多くのドキュメントが含まれています. 正式版は7.3版で,β版の7.4b2も入手できます.これらは, ftp://ftp.cs.berkeley.edu/ucb/tcl/から入手可能です.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q2- 私のマシン上で Tcl を動かすために必要な情報を得るには?

    Tcl の配布物の中から"porting.notes" というファイル名のファイルを探して見ましょう. これには,これまで多くの人々から寄せられた, 様々なマシンや OS 上で Tcl を動かす際の注釈事項がまとめられています. また,コードに触ったりする前にまず最初に読むべき, "README"というファイルもあります (これは,どんなパッケージにも言えることですけど).

    この文章の終りの方には, 様々なプラットホーム上でインタプリタを構築することに関連した 幾つかの質問と答えが納められています.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q3- TclとCを組み合わせるには?

    TclはCコードと組み合わせて使用する事を想定されています. このために,これら2つを組み合わせる様々な方法が提供されています. 以下に,それらのうちの幾つかを示します (詳細はマン・ページを参照して下さい): 最後の2つは,その他のコマンドと同レベルの機能を提供するものではありません. が,(C側の)ソースコードをアクセスする事ができない場合には,必要となるでしょう.

    これらの機能のより詳細を解説したドキュメントがあります. 拡張Tclの配付品に含まれる, TclCommandWritingマンページを参照すると良いでしょう. これはまた,WWWで, http://psg.com/~joem/CmdWrite.htmlからみる事もできます.

    LarryのTcl FAQの第2部や,Tcl参考文献録もまた, その他の参考文献について述べています.

    標準Tclに数々の拡張を組み込んだり,タイマやファイル・イベント,Xイベントや, expectを介した仮想ttyからの駆動,Tkでのアイドル・コールバックのハンドルに 関しては,組み込みTkを参照するとよいでしょう.以下から入手できます. ftp://ftp.std.com/pub/drh/et1_0.tar.gz

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q4- 欲しい機能全てを提供できるように, 数々の拡張を組み合わせるには?

    簡単な答えとしては,Tcl_AppInitを, 欲しい拡張の初期化プロシージャ全てを呼び出すように改造することです. これはTclソース配付品から,tclAppInit.c(Tkの場合は,tkAppInit.c)をコピーし, 変更した上で,使用しているTclライブラリに追加する事で行えます. 例えば,標準のTcl_AppInitは,以下の形式を取っています:
        int
        Tcl_AppInit(interp)
            Tcl_Interp *interp; /* Interpreter for application. */
        {
            /* ... */
    
            if (Tcl_Init(interp) == TCL_ERROR) {
                return TCL_ERROR;
            }
    
            /* ... */
        }
    
    「foo拡張」を追加するには, 次のようにfooの初期化関数の呼び出しを追加してやります.
       int
       Tcl_AppInit(interp)
           Tcl_Interp *interp; /* Interpreter for application. */
       {
           /* ... */
    
           if (Tcl_Init(interp) == TCL_ERROR) {
               return TCL_ERROR;
           }
    
           if (Foo_Init(interp) == TCL_ERROR) {
               return TCL_ERROR;
           }
    
           /* ... */
       }
    
    より詳細な情報は,Tcl_AppInitのマンページや, tclAppInit.cファイル自体を参照すると良いでしょう.

    (前述の)単純な回答はすべての場合に動作するものではない,というのが, より完全な回答です.多くの拡張は,より複雑な改造と, その拡張の使用に依存した組み込み方を必要とします.

    拡張Tclを組み込みたい場合,Tcl_AppInitは, その配付に含まれるものを用いねばなりません. またプログラムをリンクする際には,標準Tclライブラリより前に拡張Tclの ライブラリをリンクしなければなりません.例えば:

       cc -o mytclsh mytclXAppInit.c -ltclx -ltcl ...
    
    あるいは,Tkを組み込んだインタプリタでは:
       cc -o mywish mytkXAppInit.c -ltkx -ltk -ltclx -ltcl ...
    
    その他の手段としては,Make-A-Wishのような, 拡張を組み合わせる手助けをしてくれるパッケージや, 他のよく使われる拡張と組み合わせるさいに使用することのできる設定ファイルを 含んだ拡張も存在します.例えば,Sven Delmas によって書かれた幾つかの拡張は, 指定された拡張を組み込んだインタプリタを構築するMakefileを生成するための, configureのオプションを指定することができます. これらのパッケージの所在地に関しては,LarryのFAQのpart04〜05を参照して下さい.
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q5- 動的ローディングって何ですか?

    動的ローディングに関する議論は,しばしばcomp.lang.tclで見掛けられます. そして,さまざまな拡張の組み込みを 動的ローディングによって提供しようとするその願いは正しいものです. が,標準Tcl配付品では現在その機能はサポートされていません.

    loadコマンドの文法自体は,既に考え出されています. 後は,数多くのプラットホーム上での実装の問題となっています (プラットホーム依存の種々の問題が存在するのです).

    以下は,1993年6月14日にJhon Ousterhoutによって書かれたメッセージからの 引用です.

    [1993 Tcl]ワークショップにて,私達は動的ローディングの簡単なTclコマンド・ インタフェースの標準化を決定しました.コマンドの文法は以下の通り:
           load <file>
    
    ここで<file>は,libtcl.soの様な,動的に読み込まれるオブジェクト・ ファイルの名前です.この名前の部分は,それぞれの システムローカルな設定によって変わり得るでしょうが,先の例ではtclの様に, パッケージのプリフィックスの部分をパッケージ名とします.
    loadコマンドは,指定されたオブジェクトファイルを読み込み, ファイル名からパッケージのプリフィックス部分を取り出して, プロシージャ<prefix>_Initを実行します. ここで<prefix>は,最初の1字を大文字化したパッケージ・プリフィックスです. 例えば,Tcl_Init,Dp_Init,Tclx_Initなどが考えられます. 読み込み可能なパッケージは,(Tcl_Interp *)1つを引数として取る 初期化プロシージャを含んでいなければなりません:
           int Dp_Init(Tcl_Interp *interp);
    
    初期化プロシージャは,そのパッケージに含まれる全てのTclコマンドをインタプリタに 追加し,加えてその他のパッケージ固有の初期化処理を行います. その返値は標準Tcl完了コードやエラーメッセージ,あるいはインタプリタの戻値で, loadコマンドの返り値として用いられます.
    幾つかのプラットホーム上での実装は, 既に利用可能(例えばShellパッケージ)です. 詳細は,ソフトウェアカタログ(LarryのFAQのpart05)をカタログを参照するか, Kevin Kenny が1994年Tclワークショップに書いた論文: http://crdis1.ge.com/papers/gecrd/mtl/mdip/tcl94/00header.htmlを 参照して下さい. いずれこれらが,標準配付に組み込まれることが期待されます.
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q6- Tclがインストールしてない環境でも動作する, スタンドアローン・プログラムを作るには?

    Earle Lowe (lowee@cpsc.ucalgary.ca) は,次のように答えてます:

    TCL/Tk が存在していてもいなくても関係なくどこででも動作できる スタンドアローンのプログラムを作りたいならば, もう少し作業する必要があります.
    基本的には,これにはまず, TCL初期化ファイルをC文字列に変換してやることからはじめます. そして,Tcl_Init()Tk_Init()を呼ぶ代わりに, 変換された C 文字列を引数にTcl_Eval()を呼んでやります.
    Alexei Rodriguez (alexei@cis.ufl.edu)が作成した, wish_compiler パッケージを以下から入手することを勧めます. ftp://ftp.aud.alcatel.com/tcl/code/wish_compiler.shar.gz
    このパッケージにはtcl2cコンバータが入っていて, その使用法の説明もついて来ます.
    Makefile のちょっとした技を使えば, TCL/Tk の目的通りの使用 (様々な種類の wish を用いた,インタプリタ型言語としての使用)法で用い, コードを実行させる時には, コンパイルされたスタンドアローンプログラムを生成する様にすることも できるでしょう.
    [訳注:]
    訳者が理解しているところでは,TkWWW が,この技を使っています.
    他の選択肢として,「組み込みTk」を利用することも可能です. これは, ftp://ftp.std.com/pub/drh/et1_0.tar.gzから入手できます.
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q7- tclshがインストールされている場所に関係なく, スクリプトを動作させるには?

    または,「絶対パスを指定する事なしに,tclshをスクリプトに自動的に渡すには」.

    幾つかの技が知られていますが,もっとも一般的なのは, Tclではコマンド行も含めてバックスラッシュ{\}が継続行の印として使える, という機能を利用したものです. 例えば,

    #!/usr/local/bin/tclsh
    puts "Hello World"
    
    とするかわりに,以下のように書く事もできます.
    #! /bin/sh
    # 次の行は/bin/shでは実行されるが,Tclではコメント扱い \
      exec tclsh $0 ${1+"$@"}
    puts "Hello World"
    
    こうすることで,実際にtclshが何処にインストールされているかに関係なく (ユーザの環境変数PATHにインストールされたパスが含まれている必要はありますが), 動作させることができます.
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q8- 何で<ほげほげ拡張>が デフォルトの配付に含まれてないの?

    しばしば,ある言語拡張が(彼らにとっては必要不可欠であるにもかかわらず) なぜ,コア言語に統合されていないのかと聞かれます.

    実に多くの人々が様々なシステムの上で, 非常に幅広い用途のためにTclを使用しているのだ,ということを考えに 入れねばなりません. また,Tclは元もと, プログラマがその作成するアプリケーションに必要なスクリプト言語をいちいち 作成する手間を削減するために設計された, 最低限のプログラミングの構成と枠組を提供する 組み込み用の言語であることも忘れてはなりません.

    とは言うものの,コアTcl言語はここ数年で大きく発展して来ました. 追加された機能のうちの幾つかは,他で開発された拡張から組み込まれたものです. 拡張によって提供される機能がTclの全てのユーザにとって嬉しいと思われた場合, JhonはコアTclにそれを組み込んで来ました. 例えば,連想リストやファイル入出力コマンド(と,ファイルハンドラ), unknownプロシージャや,標準Tclに組み込まれる前の拡張Tclの諸機能が例として あげられます.Tk 4.0では(そして,Tk4.0b2では現在), Tcl 7.x/Tk 3.xとは別の作者が開発した addinputとphotoウィジェットの機能と同等のものが組み込まれています.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    プログラミング関連の質問と回答:

    From: Tcl Q&A
    Subject: Q9- 連想リストや属性リストを生成/ 使用するには?

    拡張 Tcl の配列や,キー付きリストを使うと良いでしょう.

    例えば,以下のようにプログラムしたなら:

      keylset ttyFields ttyName tty1a
      keylset ttyFields baudRate 57600
      keylset ttyFields parity strip
    
    ここで "echo $ttyFields" を実行すると,以下を得ます:
      {ttyName tty1a} {baudRate 57600} {parity strip}
    

    あるいは,配列を使って以下のようにする手もあります.

      set ttyFields(ttyName)  tty1a
      set ttyFields(baudRate) 57600
      set ttyFields(parity)   strip
    
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q10- Tclで乱数を生成させるには?

    拡張Tclには,これを行うrandomというコマンドがあります. 例えば,0から9までの乱数を生成するならば,
    set random_number [random 10]
    

    また, 乱数生成器の種を設定するsrandomというコマンドもあります.

    すべてTclで書かれた, 幾つかの仮想乱数生成関数がcomp.lang.tclに投稿されています. それらの一覧は,Larryの"tcl-faq/part04"を参照して下さい.

    種に使える値を得るには, 以下のうちの1つ(か,その組合せ)を用いると良いでしょう.

      [pid]
      [file atime /dev/kmem]
      [getclock]                        (拡張Tclのみ)
    
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q11- あるプロシージャから返される 複数のパラメータを,別のプロシージャに引数として渡すには?

    y は複数の引数を要求し,x は複数の語を返すとします. Tcl の evalコマンドを使ってやります:
    eval y [x]
    
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q12- 配列をプロシージャに渡すには?

    もし可能であるならば,グローバル変数を使うよりも, upvarコマンドを試して見るべきです. もし関数がイベント駆動であるならば, グローバル変数を使わざるを得ませんが.
    # 配列の要素を出力する
    proc show_array arrayName {
        upvar $arrayName myArray
    
        foreach element [array names myArray] {
           puts stdout "${arrayName}($element) =  $myArray($element)"
        }
    }
    
    set arval(0) zero
    set arval(1) one
    show_array arval
    
    上に示したように,プロシージャから配列を返させるには, 配列名を引数として与えてやるだけです. 配列に対して行ったどのような変更操作も,親(呼出元)の配列に反映されます.

    拡張 Tcl は,キーと値の組合せのリストである,キー付きリストと呼ばれる コンセプトを導入していて,ネットワーク経由などでも,値をルーチンに引き 渡すことが出来ます.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q13- 外部コマンドを実行して, その出力をパイプを通して読むには?

    例えば,幾つかのファイルに対して grep でパターンマッチを行うならば, 以下の方法などが考えられます:

    karl@NeoSoft.com (Karl Lehenbauer) が書く所によれば:

      set files [glob /home/cole/stats/*]
    
      proc parseInfo { site } {
         global files
      #
      # site is chosen from a listbox earlier
      #
         set in [open [concat "|/usr/bin/grep $site $files"] r]
    
         while {[gets $in line]<-1} {
            puts stderr $line
         }
         catch {close $in}
      }
    
    問題点: マッチした文字列が,ディレクトリ順に戻ら*ない*.

    一方, もしリターン・コードをチェックし,かつ,コマンドの出力を使いたいならば, Kevin B. Kenny (kennykb@dssv01.crd.ge.com)の書く所によれば:

      if [catch {exec ls} data] {
            # execでエラーが起きたならば,その終了ステータスが$errorCodeに返る.
      } else {
            # execが正常終了
      }
      # どんな場合でも,`data' には子プロセスの出力全てが格納される.
    
    Karl Lehenbauer (karl@NeoSoft.com) がerrorCodeを, 文字列 "CHILDSTATUS", 子プロセスのプロセスID, 子プロセスの終了ステータスの 3 つの要素を持つリストとして加えた点に注意して下さい.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q14- スクリプト中で プロシージャの定義を削除するには?

    プロシージャ名を無名(空文字列)にリネームします.例えば,
    rename procedureName ""
    
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q15- 7桁以上の倍精度の精度を得るには?

    Tcl 7.x では,グローバル変数tcl_precisionを1〜17の範囲で setします.例えば:
       % expr 4*atan(1)
       3.14159
       % set tcl_precision 0
       can't set "tcl_precision": improper value for precision
       % set tcl_precision 3
       3
       % expr 4*atan(1)
       3.14
       % set tcl_precision 16
       16
       % expr 4*atan(1)
       3.141592653589793
       % set tcl_precision 18
       can't set "tcl_precision": improper value for precision
    
    Tcl 6.xでは,tclExpr.cモジュール中で%gの代わりに%lfを使うように 書き換えねばなりません.
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q16- 非組み込み呼出の発生をトラップするには?

    見付けられないコマンドが呼び出された際には, プロシージャunknownが, (見付けられなかった)コマンド名とその引数を引数にして自動的に呼び出されます. 実際の所,Tclや拡張Tclは,この機能を, コマンドやライブラリの自動読み込みの機能を実現するのに使用しています. また,"tclsh"や"tcl"シェルを対話的に用いる場合, 外部コマンドの実行を(最初に"exec"と打ち込まなくとも)可能に しています.

    従って,unknownプロシージャを書き換えれば, 独自の機能拡張を行えます. 望むならば,自動読み込みの機能を削除することさえも可能です.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q17- 環境変数の読み出しや設定を行うには?

    例えば,次のように行います.
      set olddisplay $env(DISPLAY)
      set env(DISPLAY) unix:0
    
    答えてくれた Joel Fine (joel@cs.berkeley.edu)に感謝します.

    環境変数が存在しているかどうかを調べるのは,次のようにします.

        if [info exists env(VARNAME)] {
                # 環境変数が定義されているので,それを使う.
                set value $end(VARNAME)
        } else {
                # 環境変数が設定されていないのでデフォルト値を使う.
                set value "the default value"
        }
    
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q18- 頭に0が付いた数字を扱うには?

    Dave Morriss は次のようにプログラムして,頭を抱えてしまいました:
      set index [expr [exec date +%W]%[llength $pop_server_list]]
    
    08と09は,Tclでは正しい8進数ではないため, 1年のうち,8番目と9番目の週でエラーが発生してしまうのです. 実際には,Tclは頭に0がついた数を8進数として評価しようとし, それが失敗した場合は(8や9は,8進数には含まれない数字なので), 浮動小数点数として評価しようとします. が,%(剰余)関数はオペランドが整数でなければなりません. このため,エラーとなります.

    幾つかの解がありえます. George A. Howlett (george.howlett@att.com) によれば:

      set wknum [format "%g" [exec date +%W]]
      set index [expr [exec $wknum%[llength $pop_server_list]]
    
    Fred Feirtag <feirtag@wave.nrl.navy.mil> の解は:
      set index [expr (1[exec date +%W]-100)%[llength $pop_server_list]]
    
    Dan R. Schenck <schendr@Texaco.COM> からは:
      set index [expr [string trimleft [exec date +%W] 0]%[llength $pop_server_list]]
    
    Jay Goldberg (jayg@accessware.com) は, (日付を扱う)この場合には,上記の全ては動作するが, 一般的には動かないこともあり得ることを指摘しています.

    むしろ,以下のコマンド:

      regsub 0+(.+) 元の文字列 \\1 新しい文字列
    
    を使って先頭の 0 を除去すべきでしょう.先の例に当てはめるならば,
        regsub 0+(.+) [exec date +%W] \\1 weeknum
        set index [expr $weeknum%[llength $pop_server_list]]
    
    の様になります.
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q19- コマンドライン引数を 参照したいのですけど?

    プログラム名はグローバル変数 argv0 に代入され,その引数はグローバル変数 argv にリスト形式で格納されます.変数 argc には,argvのリストの要素数が 納められます.例を示すならば:
       #! /usr/local/bin/tclsh
       if { $argc != 2 } {
            puts stderr "$argv0: Usage: $argv0 <infile> <outfile>"
            exit 1
       }
       set infile  [lindex $argv 0]
       set outfile [lindex $argv 1]
    
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q20- 例えばcase文中などに, コメントを書きたいのですが?

    コメントは,置きたい所にそのまま置くことはできません. そうしたい場合は,コメントを "{" の内側に移動しましょう.例えば,次のように書きます.
    case 1 {
      -1    {
            #
            # 情報が見付けられない場合
            #
            exit 2
            }
       0    {
            #
            # 引数にエラーがある場合
            #
            exit 1
            }
       default    {
            #
            # 望む情報が見付けられた場合
            #
            exit 0
            }
    }
    
    Gerald W. Lester (gwlester@cpu.com) に感謝.
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q21- バイナリ・データの読み書きをするには?

    拡張 Tcl では,次のように,これを安全に行えます.
      set infp [open "|compress -dc $fileName"]
      set outfp [open "|gzip -c $newFileName" w]
    
      copyfile $infp $outfp
    
    コードの例を提供してくれた karl@NeoSoft.com (Karl Lehenbauer) に感謝.

    標準 Tcl でバイナリ・データを 1 文字として扱う方法は, 以下で見つけることができます.
    ftp://ftp.aud.alcatel.com/tcl/code/binary-io-hack.shar.gz

    この他にも,バイナリデータの扱いを可能にするtclbinとBinarIOという 2種類の拡張が存在します.前者は構造体データを扱えるという利点があり, 後者はバイナリ・データ・ストリームでより効率良く動作する利点があります.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q22- シグナルをトラップするとか, その他のUnix固有の機能を使うには?

    拡張Tclは,たくさんのこの手の機能を提供しています. 例えば,拡張Tcl には "signal"コマンドがあります.
    signal action siglist [command]
    ここでactionは, "default", "ignore", "error", "trap", "get"に加えて POSIXの"block"と "unblock"アクションのいずれか (もちろん,POSIX システムでのみ有効). siglistは,記号表現,あるいは数値表現のUnixシグナルのリスト (前置記法 SIG はオプション). commandは,定義するエラー・ハンドラ (あるいは,単に, {puts stdout "そんなキーは押さないで!"} :-).
    "trap" は期待通り動きますし,"error"と"get" は, キーボード・トラバーサルが必要な会話的プログラムでは,とても有効です.

    拡張 Tcl は,forkなどの機能も持っています.

    回答は Brad Morrison (brad@NeoSoft.com)から寄せられました.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q23- 間接指定をしたいのだけど. -- 何で$$varが動かないの?

    インタプリタで評価される度毎に,たかだか1レベルのみの置換だけが可能なのです. また,変数置換の発生時には,インタプリタはドル記号を見つけると,それに続く 不正な文字に至るまで全ての文字列(ここで不正とは,英数字,及び下線記号以外の 文字として定義される)を変数名として扱います.従って,配列記法や ${varname}形式では区切りとして認識されます.

    $$varの場合,ドル記号の後の最初の文字が不正文字(次のドル記号)であるので, 変数名が存在しない事になり,変数置換は働きません (2番目のドル記号はそのまま残ります). そして残りのドル記号のための構文解析が開始され,その右側が変数名として 扱われます.このため,直ちに2番目のドル記号以降が変数置換され, 構文解析はそれ以降の置換がないかどうかを調べにいってしまいます. それ以降何もないならば,インタプリタを通したこのパスによる置換は 終了します(1回のみ行われることに注意).

    evalコマンドはその引数をインタプリタに通します.そこで,2回目のパスを インタプリタに通すためにevalを使う事ができ,そうすれば$$varを動かす事が できるでしょう:

       % set a 5
       5
       % set var a
       a
       % puts $$var              # 動かない
       $a
       % eval puts $$var         # 動く.--- けど危険.
       5
    

    ですが,変数varの内容に特殊な文字(スペースやセミコロンなど)が 含まれていると,問題が発生してしまうでしょう.

    よりよい方法は,1引数のみ与えられた場合のsetコマンドの振舞を応用し, コマンド置換を変数置換に組み合わせて使用するのです:

       % puts [set $var]         # 安全に動作.
       5
    
    また,実際にはコマンド置換(一度に1組の[]にしか働かない)だけを使っても できます:
       % puts [set [set var]]    # 同じように動作
       5
    
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q24- クォートされた文字列を 意図した通りに動かすには?

    この問題点を扱った長文の記事が,以下で得られます.
    ftp://ftp.aud.alcatel.com/tcl/docs/README.programmer.gz

    ここに掲載するのは,短い答えです:

    Q. 後になって実行するコマンドを組み立てようとしてるのですが, 空白や特殊文字を値に含む変数で問題が出てしまいます.

    A. コマンドを組み立てる最も安全な方法は, list コマンドを使うことです. そうすれば,リスト構造を壊さずにすみます. 余計なエバリュエータによる評価が行われてしまうこともあるので, ダブルクォートの使用は避けましょう. 例題として, クリックしたら表示しているラベルを出力するボタンを生成するプログラムを 示します.

    間違えた答え #1:
    button $myname -text $label -command "puts stdout $label"
    なぜ?
    それは,もし$labelが空白文字を含むなら, putsコマンドに間違えた数の引数が渡されてしまうからです. $labelが$や[]文字を含むなら, 出力されずに評価されてしまいます.

    良い答え #2:
    button $myname -text $label \
           -command [list puts stdout $label]
    なぜ?
    list$labelの値を適切にクォートするからです.
    Q. 後になって実行するコマンドを組み立てようとしてるのですが, 変数が組み立て時に評価されてしまったり, コマンドの実行時に評価されてしまったりして,思い通りに動いてくれません.

    A. これを行う最も明晰な方法は, 実行時の変数の使用を隠蔽するようにプロシージャを定義することです. そして,前に述べた様に listコマンドを用いてプロシージャの呼び出しを組み立てあげます. (実行中であってもプロシージャの定義は可能です. 別のプロシージャの内部で生成されても, それはグローバルなスコープを持ちます.)

    間違えた答え #1:
    button $myname -text $label -command \
           [list puts stdout $ArrayOfDynamicStuff($label)]
    なぜ?
    配列変数はボタンが生成された時の値で置き換えられてしまい, ボタンがクリックされた時の値とはならないからです. また,コマンドがグローバルなスコープで実行されることにも 注意しなければなりません. そのため, "global ArrayOfDynamicStuff"を コマンドの中に含める必要はありません.

    間違えた答え #2 (バッククォートと list):
    button $myname -text $label -command \
           [list puts stdout \$ArrayOfDynamicStuff($label)]
    なぜ?
    これでは,listコマンドと $ のバッククォートが, 互いに喧嘩してしまいます.結果として全体の振舞いは以下の様になり,
    puts stdout {$ArrayOfDynamicStuff(foo)}
    配列要素の値に対する置換が働かなくなってしまいます.

    いかがわしい答え #3 (バッククォートとダブルクォート):
    button $myname -text $label -command \
           "puts stdout \$ArrayOfDynamicStuff($label)"
    なぜ?
    これは$labelの値が特殊文字や空白文字を含まない時だけ, まともに動きます.

    完全な答え #4 (proc):
           proc doit { i } {
              global ArrayOfDynamicStuff
              puts stdout $ArrayOfDynamicStuff($i)
           }
           button $myname -text $label -command [list doit $label]
    なぜ?
    ボタンのために簡単なTclプロシージャを作ってやる様にしておけば, ちゃんと動作してくれます. 何故なら,凝ったクォーティングをする必要をなくしてくれますし, ボタンから起動される処理の仕様変更も,容易になります.
    Q. プロシージャに可変個数の引数を渡そうとしてるのですが, $argsを正しく展開するところで,つまってしまいます.

    A. evalとダブルクォートを組み合わせて使おうとするのは, 止めましょう. なぜなら,そうすると,余計な評価が起動されてしまうからです. evalコマンドは,その引数が1つ以上の場合は,それらを1つに連結します. そのため,ダブルクォートで1つに括ってやる必要が,まったく無くなります. 前述のbuttonの例を拡張して見ましょう.

    間違えた答え #1:
           proc mybutton { myname label args } {
              button $myname -text $label \
                  -command [list puts stdout $label] $args
           }
    なぜ?
    変数$argsに格納されている mybuttonへの全ての追加引数は, 1つのリスト要素にグループ化されてしまっています. しかしながら,buttonコマンドはその引数に, サブリストではなく個々の引数を要求するからです.

    間違えた答え #2:
           proc mybutton { myname label args } {
              eval "button $myname -text $label \
                      -command [list puts stdout $label] $args"
           }
    なぜ?
    ダブルクォートは,$argsと同じように, $labelの展開を可能にします. そのため,$labelの値に空白文字が含まれるなら, buttonコマンドには, 正しくない引数並びが渡されることになってしまいます.

    良い答え #3:
           proc mybutton { myname label args } {
              set cmd {button $myname -text $label \
                       -command [list puts stdout $label]}
              eval $cmd $args
           }
    なぜ?
    evalは,最初に 2 つの引数を連結して, 次にその結果をインタプリタを介して実行します. これは,$cmd$argsから, 外側のカリー括弧を外して, 2つの変数の全ての要素を1つのリストにすると考えられます. $labelは,1回しか評価されません. そして,putコマンドも正しく動きます. さらに,argsが入れられる度にも,1回しか処理しません.
    Q. なんで if/while/for文で 文法エラーになってしまうのでしょう.

    A. ひょっとして,

        wish: set foo bar
        wish: if {$foo == bar} {puts stdout bar}
        syntax error in expression "$foo == bar"
    
    の様に書いてはいないでしょうか.

    これでは,文字列としても変数としても評価されません. 式中のオペランドとしての文字列は, ダブルクォートか中括弧で括ってやらねばなりません.

        wish: if {$foo == "bar"} {puts stdout bar}
    
        wish: if {$foo == {bar}} {puts stdout bar}
    
    の様に書き換えましょう.

    どちらを選ぶかは,展開させたいかどうかで決めて下さい.

    この記述は,Jesper Blommaskog (d9jesper@dtek.chalmers.se) からのコントリビュートです.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q25- プロシージャ定義を 複数のスクリプトで共有するには?

    明示的にファイルをsourceするのではなく, Tclライブラリを作るようにしましょう.
    Step 1. ファイルを共有ディレクトリに置きます.
    Step 2. "ライブラリ" のための,tclIndex を作ります.
    私は Makefile 中に,次のように書いています.
           install.index:
               (cd ${DESTDIR}/tclscripts/lib; \
               echo 'source /usr/local/lib/tcl/init.tcl;\
    	   auto_mkindex . *.tk' | tcl ; exit 0)
           
    Step 3. 作成した Tcl スクリプトに, ライブラリを参照させるようにします.
    例えば,以下のようにします.
           # local additions
           lappend auto_path /usr/local/lib/tcl_local \
                $env(RDS_TCL_SCRIPTS)/lib
           
    このようにすれば, スクリプトはプロシージャをライブラリの中から参照しようとし, "unknown"コマンドが 自動的にプロシージャを読み込んでくれます.
    この記述は,Joe VanAndel (vanandel@ncar.ucar.edu)からの コントリビュートです.
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q26- リストに挿入された要素を得るには?

    よく,なぜ
      linsert $list 0 ..
    
    と実行したのに,結果に .. が挿入されていないのかと聞かれます.

    Jesper Blommaskog (d9jesper@dtek.chalmers.se)が, 以下のように答えています.

    lappend以外のリスト操作では,戻り値を保存しなければなりません. これは,list,lindex,lrange,lreplaceに 当てはまります.
    これは,ひょっとしたらやりたかった事が正しく動く例です.
      set list [ linsert $list 0 .. ]
    
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q27- ファイル識別子から 非ブロック化入力を行うには?

    Frank Smith (frank@arraysystems.nstn.ns.ca)によると, 拡張 Tcl を持っているなら,
      read $fileId [fstat $fileId size]
    
    のようにして実現可能だそうです. これは,fileIdからその時点で読み込める最大のバイト数を読み込み, 結果としてブロック化しません.
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q28- デッドロックさせずに パイプで入出力するには?

    標準入出力パッケージは, (入出力する)文字をバッファリングして 不必要なシステムコールを行わなくて済むようにすることで, 処理速度を最適化しています. これは会話的な使用には不適切ですので, 標準入出力はその振舞いをファイルが端末である場合には変更します. (ですが)パイプに書き込む時には,端末に書き込んでいる訳ではないので, 書き込んだ出力はバッファリングされてしまいます. 同様に,パイプの向こうにある他のプログラムがその応答を出力する時にも, バッファリングされてしまいます. 結果として,パイプの両端のプログラムは, 互いに入力を待って立往生してしまいます. これを解決するには,Tcl ではflushコマンド, C ではfflush()を使ってパイプをフラッシュすることです. もっとも, しばしば,パイプラインの端のプログラムの制御が出来ない場合もあります. その様な場合は,解決する唯一の解は,仮想端末(pty)を使う事です. が,これはそう簡単に行えることではありません.

    これは標準の Tcl ではサポートされていませんが,expect では, spawnコマンドで ptyを開いてコマンドを起動する機能をサポートしています.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q29- 実行中のバージョンを知るには?

    だれも答えてくれる人はいない様ですが,大丈夫. Tcl 自身が,そのバージョンを答えてくれます. 以下のように打ち込んで見ましょう.
      info tclversion
    
    また,Tk のバージョンは,以下のようにして知ることが出来ます.
      puts $tk_version
    
    その他の拡張では,他の手段があるでしょう(例えば拡張Tclでは, "infox version"でバージョン情報が得られます).
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q30- 配列名を入れた変数を使うには?

    Eric Bleeker (ericbl@paramount.nikhefk.nikhef.nl)が 書く所によれば:
    ひょっとしたら,こんな風に書いていませんか:
        % set foo "bar baz"
        bar baz
        % foreach aap $foo {
    	    set $aap(1) "something"
        }
        can't read "aap(1)": variable isn't array
    
    これは,Tclが配列要素"aap(1)"を, 存在してもいないのに置換しようとしているのです. これを解決するには,以下のようにします.
        % foreach aap $foo {
    	set [set aap](1) "something"
        }
    
    この場合は,2 つの配列"bar"と "baz"は生成されます.
    別の形式として,以下のような形も考えられます.
       % foreach aap $foo {
           set ${aap}(1) "something"
       }
    
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    プラットホーム固有,あるいは移植性に関する質問:

    From: Tcl Q&A
    Subject: Q31- Q31- AIXでTcl/Tkの共有ライブラリを 構築するには?

    Dov Grobgeld (dov@menora.weizmann.ac.il) が, AIX 3.1.5で,TclとTkの共有ライブラリを作る方法を発表しています.
    Tclでは:
           cc -o tkshar.o *.o -bE:tclshar.exp -bM:SRE -berok \
                     -lX11 -lm
           ar r libtclshr tclshar.o
           
    Tkでは:
           cc -o tkshar.o *.o -bE:tkshar.exp -bM:SRE -berok \
                     -Ltcl -lX11 -lm -ltclshr
           ar r libtkshr tkshar.o
           
    ここで tckshar.exp と tkshar.exp は,外部関数のリストです.

    AIX と IBM のフォントの問題もあります. X サーバを修正するパッチをIBMから入手する必要があり, そうすれば,フォント関連が動きます.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q32- HP-UXでTclをコンパイルできた人は いませんか?

    ポーティング ノートを参照して下さい. また,Configure が互換バージョンのopendir()を (コンパイルに)使うべきだと判断してしまうけど, dirent.h が存在していないという問題の報告が幾つかなされています. これは,globでエラーを引き起こします. TclXのreaddirでも同様です.

    tcl 7.3では,opendirの互換ファイルを削除する変更を行いましょう. そして,-DNO_DIRENT, -DUSE_DIRENT2を削除すれば,問題は解決します.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q33- VMSでTclをコンパイルできた人はいませんか?

    1993年5月4日に, John Kimball (jkimball@src.honeywell.com) から寄せられた情報によれば, 彼はTcl 6.7とTk 3.2をVMS 5.5 上にポーティングすることに成功したそうです. ファイルの情報はカタログを参照して下さい.
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q34- SCO Unixで Tclをコンパイルするには,どうしたらいいんでしょう?

    "#undef select"をtkEvent.cに加え, main.cの460行目あたりのTK_EXCEPTION の参照を削除します.

    Tkは,そのウィジェット立体表示のために, 表示枠のカラー確保のための独自の仕組みを使っています. これがTkを,"Pseudo Color" ディスプレイ・クラスで, 16セルのカラーマップのマシン上で実行する際に問題となります.

    8bitプレーンを使えないならば, ディスプレイ・クラスを "StaticColor" にする様に, サーバを "-static"(Xsco) や "-analog"(Xsight)オプション指定で立ち上げるとよいでしょう. これは,カラーマップを完全に読み込みのみとし, 要求された色にできるだけ最も近い色を返すようにします.

    この情報は, Keith Amann (Keith_Amann@stortek.com)から寄せられました.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q35- tclTextを走らせると, formatやscanでエラーになるのは何故?

    この(scanf/printfの)問題は,多くのシステムで見られます. これに関しては,あまり神経質になる必要はありません --- `より高度な'機能が使えないだけです. もしあなたがCのハッカーならば,同じ問題に出喰わす筈です.

    実例をあげるならば,printf("%Ng", double_value)と strtod("+",&terminal)は誤った結果をもたらします.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q36- tclTextを Irix 4.0.1で走らせると一杯エラーが出るのは何故?

    これは,4.0.1のオプティマイザのバグで, 4.0.2では修正されています. tclVar.cをオプション-O0(最適化無し)でコンパイルして下さい.
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q37- Crayで Tclを問題なく走らせた人はいませんか?

    ポーティング・ノートの変更点に関する記述を参照して下さい. また,Booker C. Bense (benseb@grumpy.sdsc.edu)は, バージョン 3.0.1.6 ではキャラクタ型のポインタの深刻な問題があり, Tclがクラッシュすると報告しています. バージョン 3.0.2.1 を使うと多少はマシですが, formatコマンドの些細なバグと, scanコマンドの深刻な問題は残るそうです.
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q38- Tcl 7.1/Tk 3.4をNeXTSTEP 3.1で 走らせるには?

    この問題に関しては,以前,大きな議論の元となりました.以前の記述を, この分野のオーソリティと思える方からの解説に置き換えることとします.

    Robert Nicholson (robert@steffi.demon.co.uk) によれば:

    これはTCL7.1 と TK3.4 を対象とします.

    これは Thomas Funke のエントリです.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q39- TclをNextにインストールするには?

    tcl7.1をNeXTSTEP 3.1にインストールするには,以下のようにします:
    configure を既定義のCPPで実行:
    ボーンシェルを実行するために,"sh"と打ち込みます. そして,以下のようにタイプします.
           CPP='cc -E' ./configure
           
    Makefile を編集:
    tmpnam.oをCOMPAT_OBJSに追加:
           COMPAT_OBJS = getcwd.o waitpid.o strtod.o tmpnam.o
           
    この時,NeXTライブラリlibsys_a.aで供給されるものに対して, strtodtmpnamを区別するために, 何か適当な名前に変更したいと思うでしょう. これを行うためには, AC_FLAGSに以下の行を付け加えることで出来ます.
           -Dstrtod=newstrtod -Dtmpnam=newtmpnam
           
    名称変更された関数の定義は,compat/*.cにあります.
    全てが正しく動くかどうかをチェックするには, tclshを起動し,以下を実行します.
      % expr {"0" == "+"} 
      0
    
    間違えたstrtod関数を用いていたならば,返り値は1になり, 深刻なエラーとなります.精度に関するエラーは無視します.
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q40- TclをNextにインストールするには?

    Tk3.4 の中にもstrtod関数の呼び出しがあるので, 前述の../tcl-7.1/compat/strtod.oにリンクを張り, AC_FLAGSに-Dstrtod=newstrtodを付け加える必要があります.

    注意: Tk の raise 試験は, ウィンドウマネージャにtvtwmを使っていると失敗します. この試験を通すためには,twmやfvwmなどに変更する必要があります.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q41- Tcl/Tk本のドラフトを 印刷できないのですけど.

    John Ousterhout (John.Ousterhout@Eng.Sun.COM) によると:
    私のところに届いてる知らせによると, 多くの人々が,この本の一部の印字出力で問題を抱えているようです.
    古いバージョンのTranscriptスプーラ・ソフトウェアには, ページが逆順になったPostScriptファイルの中では, 別のencapsulated PostScriptファイルを扱えないものがあるようです. これらは,ページ構造をごっちゃにする傾向があり, 最初のEPSファイルのところで,エラーになってしまいます. 第2部にはスクリーンダンプを載せるために, 沢山のEPSファイルが埋め込まれています. もし,このファイルを印字出力できないなら, ページ逆順出力が可能となってるかどうかを見て下さい. もしそうであるならば,利用しているシステムのウィザードに言って, 一時的に不能にしてもらいましょう. これで,出力可能になる筈です. あるいはスプールソフトウェアを経由せずに, 直接プリンタに送る手を考えるのもよいでしょう (例えば,プリンタの継ってるシリアルポートに, 直接catしてしまうとか).
    他にも,次の助言が寄せられています.
    組み込まれた図は,行の区切りに LF ではなく CR を使用しているため, これが問題の原因となる場合があります. これらを LF に変換して見ましょう.
           tr '\015' '\012' < book.p2.ps > fixedbook.p2.ps
    
    そして:
    これはオリジナルの投稿者の責任ではありませんが, 出力紙にA4を使っている国で, Dataproducts LZR1260E の様なプリンタを使用している場合, 印字用紙サイズが縦方向に引き延ばされてしまうことがあります. これは,他のFramemakerで生成されたファイルでも発生します. 疑いもなく PS インタプリタのバグでしょう. 修正には,A4用紙の大きさを編集してやります. 以下のシェルスクリプトは,これらの問題を両方とも修正します.
       #!/bin/sh
       cat $1 | tr '\015' '\012' | \
                sed '/FMDOCUMENT$/s/612 792/595 842/'
    
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q42- SGI Indigo上でエラーが出るのはなぜ?

    Gordon Lack (gml4410@ggr.co.uk)によれば, SGIのCコンパイラには変数引数の扱いにいくつかのエラーがあるそうです.

    tclVar.cは,IRIX C 4.0.1では,変数に関するバグのため, 引数-O0でコンパイルされねばなりません.

    Makefile のルール指定を以下のように書き換えてやります.

     
    # GGR SG needs -O0 for varargs at 4.0.1
    CC_SWITCHES0 =  -O0 -I. -I${SRC_DIR} ${AC_FLAGS} ${MATH_FLAGS} \
            ${GENERIC_FLAGS} ${PROTO_FLAGS} ${MEM_DEBUG_FLAGS} \
            -DTCL_LIBRARY=\"${TCL_LIBRARY}\"
    
    tclVar.o: tclVar.c
            $(CC) -c $(CC_SWITCHES0) $<
    
    Peter NEELIN (neelin@pet.mni.mcgill.ca)は, 次のような注意をしてます.

    私は,ファイルConfig.mkを次のように変更して, TclX 7.3aをSGI(irix4.0.5)でコンパイルしました.

     
      71c71
      < CFLAGS=-cckr -D__GNU_LIBRARY__
      ---
      > #CFLAGS=
      106,107c106,107
      < TCL_PLUS_BUILD=TCL_PLUS
      < CCPLUS=g++
      ---
      > #TCL_PLUS_BUILD=TCL_PLUS
      > CCPLUS=CC
      191,193c191
      < MAN_DIR_SEPARATOR=
      < 
      < LIBOBJS=strftime.o
      ---
      > #MAN_DIR_SEPARATOR=.
    
    -D__GNU_LIBRARY が,srandom問題を解決しますが, 思うに,-cckrがwaitpidでプロトタイプ・エラーを起こします (汚いですが,とりあえず動きます). strftimeがなぜ必要だったかは,忘れてしまいました.

    私の作成した Config.mkのバージョンが欲しいならば,メールして下さい.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q43- expectをSolaris2.3で構築するには?

    Jeff Abramson (jra@hrcms.jazz.att.com)が語るには:
    SunPro cc 2.0.1を使ってもgcc 2.5.8を使っても問題はありません. SunProならば,次のようにします.
       CC=cc ./configure --prefix=あなたの選んだディレクトリ
       make CC=cc
    
    gccならば,以下の通りです.
       CC="gcc -fwritable-strings" ./configure \
    	  --prefix=あなたの選んだディレクトリ
       make CC="gcc -fwritable-strings"
    
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q44- SequentにTcl/Tkを移植するには?

    Andrew Swan (aswan@soda.berkeley.edu)によって解明されました.

    TclとTk双方で,非ANSIのSequent ccではなく,gccを用います.

    Tclでは,数学ライブラリに,2つの問題があります. 第1に,Sequentの数学ライブラリが,'fmod'関数を含んでいないことです. 私はfmodのソースをftp.uu.netから入手し, サブディレクトリcompatに入れました. そして,それをMakefileに追加しました. fmodは,'isnan'と'finite'関数を内部で使用していますが, tclが無限とnanをサポートするとは信じなかったので, それらはコメントアウトしただけです.

    数学ライブラリのもう1つの問題は, そのライブラリ中に'tanh'関数のコピーが2つ, 含まれてしまっていることです. "ar"を使ってライブラリをオブジェクトに分解し, 再度組み立て直して,tanhのコピーを取り去ってしまえば, 簡単にfixできます.

    この様な変更を行えば,Tclのコンパイルはきれいに終了し, 試験も,scanの試験以外はすべて通ります. どうも,Dynixでは,*scanf関数が壊れてる様です. この問題は,8進数の終りで確認できます. 私はちょうど,この問題に取り掛かったところです. 解決策は,*scanf関数のソースを見付けだし, それを使うことになるでしょう.

    Tkをコンパイルするために,私はwchar_tのようなものを定義した, 新しいバージョンのstddef.hを作らねばなりませんでした. 私はそれを別のインクルード・ディレクトリにコピーし, そのディレクトリを最初に指定して,それが参照されるようにしました. Tkでも数学ライブラリの問題 (tanh)が発生します. これら以外もありますが,すべてのコンパイルはきれいに終了し, すべての試験にもパスします.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q45- AU/X 3.0でシンボルテーブルが 一杯になるのを避けるには?

    AU/X 上でのソースのコンパイルが終ったならば, デフォルトのテーブルのアロケーションを拡張する -A {factor}引数をリンカに指定しなければなりません. {factor}は,デフォルトのアロケーションの何倍にするかを指定します. -A 2を試してみましょう. この移植に関するこれ以上の詳細は, Walter B. Kulecz 博士 (wkulecz@medics.jsc.nasa.govに 連絡すると良いでしょう.
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q46- MS-DOSやMacOS, その他の非UnixマシンでTclをコンパイルするには?

    Larry VirdenのFAQの,tcl-faq/part1やtcl-faq/part4 を参照すると, 関連するツールや移植の完了品, この問題を扱っているメーリングリストなどの情報が得られます.
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q47- QNXマシン上でTclをコンパイルするには?

    Steve Furr (furr@qnx.com) が示す所によれば:
    QNX 上で Tcl を動かすためにしたことをまとめるならば,
    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    From: Tcl Q&A
    Subject: Q48- Tclスクリプトを実行しようとすると "Command not found"というメッセージが出るのは何故?

    スクリプトの頭に通常置かれるTclインタプリタのパスを指す#!の部分が, 使用しているシステムには長すぎるのでしょう. 多くのUnixシステムでは,この部分の長さを32文字に制限しています. ですから,例えば:
        #! /usr/home/誰かのホーム/とっても/なが〜い/パス/tclsh
    
        # スクリプトの本体
    
    なんてのは,エラーを発生する場合があり得ます.

    tclshの実行ファイルを他のディレクトリに移動したり, シンボリックリンクを張って,パスを短くするとよいでしょう. 別の解法としては,パスをまったく指定しないという手もあります. これを行う方法は,質問 「tclshがインストールされている場所に関係なく,スクリプトを動作させるには?」 の回答を参照して下さい.

    →一般情報目次へ
    →プログラミング目次へ
    →移植情報目次へ
    

    FAQ の終り