Roundcubeのプラグインを、プラグインマネージャからダウンロードする
Roundcubeのプラグインをダウンロードする際、プラグインマネージャを使用すると
必要なプラグインを選択し、最新のものをダウンロードすることができます。
プラグインマネージャの主な機能
・簡易プラグインの配布
・プラグインのアップデート
・プラグインの関連情報
・アカウント設定に関するユーザレベルの制御
・Roundcubeデータベースの整理
・統一されたローカライゼーションの公開および配布
・ローカライゼーション翻訳の完全追跡
・プラグインのシステムの問題を報告
・リリースノートとドキュメントリンク
新しいスキンに対応したものが多いので、簡単に使用することが出来ます。
プラグインマネージャのダウンロード
プラグインマネージャの使用開始時には、他のプラグインを使っていないことが前提です。
プラグインマネージャの他に、以下のプラグインが必要になります。
・global_alias
・http_request
・jqueryui
・qtip
・settings
全て一緒に、こちらからダウンロード出来ます。
http://myroundcube.com/myroundcube-plugins/plugin-manager
ダウンロードが完了したら、プラグインディレクトリを指定し、フォルダを解凍します。
ディレクトリの場所はこちら。
<ルートディレクトリ>/roundcube/plugin |
プラグインマネージャの設定
“config.inc.php.dist” ファイルのコピーを作成し、”config.inc.php” にリネームします。
コピーしたプラグインマネージャの ”config.inc.php” ファイルをテキストエディタで編集します。
<ルートディレクトリ>/roundcube/plugin/plugin_manager/comfig.in.php |
管理者アカウントを追加します。(アカウントは複数追加できます。)
1 2 3 4 |
//管理者のアカウントを追加 |
“main.inc.php”ファイルに、”plugin_manager”を追記します。
1 2 3 4 |
//プラグインマネージャを追加 |
一緒にダウンロードされた、以下のヘルパープラグインも同様にプラグインの設定を行って下さい。
・global_alias
・http_request
・jqueryui
・qtip
・settings
Roundcubeにログインし、設定をクリックすると”Manage Plugins”という項目が追加されます。
“Manage Plugins” 下の ”Pulugins Dounloads” をクリックし、Roundcubeのバージョンを選択します。
私の場合は、 ”Download plugins for Roundcube 0.8.4″ を選択し、”I agree”(同意する) をクリックします。
ここまで進むと、以下のように表示されます。
色がついているプラグインは有料です。
必要なプラグインにチェックを入れて、”Download Zip-Archive”ボタンをクリックすると
Zipファイルがダウンロードされます。
ダウンロードが完了したら、Zipファイルをプラグインディレクトリに解凍し
それぞれプラグインの設定を行います。
試しに、”compose_in_taskbar” を入れてみます。
特に難しい設定はないので、すぐに使用することができます。
タスクバーに、メッセージの新規作成ボタンを追加するプラグインです。
もちろんクリックすると、メッセージが新しく作成されます。
他にも様々な機能のプラグインが配布されているので、自分好みの機能を追加して
使いやすくカスタマイズすると、楽しいですね♪
Roundcubeにプラグインを追加する
前回はRoundcubeのインストール&設定を行ったので、
本来の目的である、プラグインを試用していきたいと思います。
公式サイトのwikiに、使用可能なプラグインと設定の手順が載っていました。
http://trac.roundcube.net/wiki/Plugin_Repository
英語は得意ではないですが(;´Д`)カタコトなGoogle翻訳機能様を頼りつつ
なんとか読み解いて、探り探りやっていきました。
プラグインのインストールとプラグインの有効化
プラグインをインストールし、有効化します。
1、プラグインをダウンロードします。
2、プラグインディレクトリを指定し、フォルダを解凍します。
プラグインディレクトリの場所は以下になります。
<ルートディレクトリ>/roundcube/plugins/
3、解凍したフォルダの中に”config.inc.php.dist”ファイルが存在する場合は
コピーを作成し、”config.inc.php”にリネームします。
“config.inc.php.dist”ファイルに直接書き込まないよう気を付けて下さい。
“README”ファイルが存在し、設定の手順が載ってある場合は
手順に従い、設定を行って下さい。
4、’main.inc.php’ファイルに、追加したプラグインのディレクトリ名を追記します。
配列に列挙されたプラグインだけが有効になります。
‘main.inc.php’ファイルをテキストエディタで編集します。
<ルートディレクトリ>/roundcube/config/main.inc.php
//'additional_message_headers'と'archive'を追加
$rcmail_config['plugins'] = array();
// ↓
$rcmail_config['plugins'] = array('additional_message_headers', 'archive');
プラグインを無効にしたい場合は、リストから削除します。
//'additional_message_headers'を削除
$rcmail_config['plugins'] = array('additional_message_headers', 'archive');
// ↓
$rcmail_config['plugins'] = array('archive');
5、WEBブラウザからRoundcubeにアクセス、または更新を行い、追加した機能を確認します。
以上の設定を行えば、簡単に機能を追加することが出来ます。
ヘルプ機能を追加
Roundcubeをインストールした際、既にプラグインがいくつか入っていたので
試しにヘルプ機能を追加してみることにしました。
タスクバーにヘルプが追加されたので、クリックしてみると・・・
ヘルプのリンク先を指定してないので、何も表示されません。
“config.inc.php”ファイルを確認します。
<ルートディレクトリ>/roundcube/plugins/help/config.inc.php
ヘルプのリンク先を設定します。
特にページを作っていなかったので、Roundcubeの公式WikiのURLを指定しました。
//helpのリンク先を指定
$rcmail_config['help_source'] = '';
// ↓
$rcmail_config['help_source'] = 'http://trac.roundcube.net/wiki';
設定が済んだらページの更新を行い、ヘルプの内容が変更されているか確認します。
“larry”用のスキンも用意されていたので、レイアウトもバッチリです(´∀`)
Roundcubeをインストール&設定してみました
弊社でカスタマイズ&運用サポートを行っております、
高機能WebメールRoundcube!!
業種や用途等に合わせて、自由にカスタマイズできるのが特徴です。
そのままでも使用できますが、それでは普通のWebメールと変わらず(;´Д`)
どうやらプラグインを使えば、簡単に色んな機能が追加できるようなので
さっそくRoundcubeをインストールしてみることに。
とりあえず簡単にプラグインを突っ込んで試してみたいだけなので、
下記のサイトを参考にさせていただきました。感謝です!
http://pnpk.net/cms/archives/650/all/1
ローカルでメールクライアントを構築し、Gmailを利用します。
あくまで簡単に簡単に(^_^;)
GmailでIMAPを利用する場合、Gmailの設定画面で事前に
IMAP経由でのメール受信を有効にしておく必要があります。
RoundCubeでGmailを受信する場合には、
Gmailログイン→“設定”→“メール転送とPOP/IMAP 設定”→“IMAPアクセス”で
“IMAPを有効にする” にチェックをしておいてください。
Roundcubeをダウンロード
http://roundcube.net/ からRoundcubeをダウンロードします。
今回は0.8.4を選びましたが、最近0.9-beta版が出たようですね~。
Apacheのドキュメントルートにフォルダを解凍し、フォルダ名を”roundcube”にリネームしました。
私の環境ではココです。
C:/Apache/htdocs
動作環境については、roundcubeフォルダにあるINSTALLファイル内で
REQUIREMENTS(必要条件)と記述してありました。
確認確認~(´∀`)~♪
* The Apache, Lighttpd, Cherokee or Hiawatha web server
* .htaccess support allowing overrides for DirectoryIndex
* PHP Version 5.2.1 or greater including
- PCRE, DOM, JSON, XML, Session, Sockets (required)
- libiconv (recommended)
- mbstring, fileinfo, mcrypt (optional)
* PEAR packages distributed with Roundcube or external:
- MDB2 2.5.0 or newer - Mail_Mime 1.8.1 or newer
- Mail_mimeDecode 1.5.5 or newer
- Net_SMTP 1.4.2 or newer
- Net_IDNA2 0.1.1 or newer
- Auth_SASL 1.0.6 or newer * php.ini options (see .htaccess file):
- error_reporting E_ALL & ~E_NOTICE (or lower)
- memory_limit > 16MB (increase as suitable to support large attachments)
- file_uploads enabled (for attachment upload features)
- session.auto_start disabled
- zend.ze1_compatibility_mode disabled
- suhosin.session.encrypt disabled
- mbstring.func_overload disabled
- magic_quotes_runtime disabled
- magic_quotes_sybase disabled
* PHP compiled with OpenSSL to connect to IMAPS and to use the spell checker
* A MySQL (4.0.8 or newer), PostgreSQL, MSSQL database engine or the SQLite extension for PHP
* One of the above databases with permission to create tables
* An SMTP server (recommended) or PHP configured for mail delivery
私の環境は、ざっとですが以下のとおりです。
・OS Windows7
・PHP Version 5.3.13
・Apache/2.2.22
・mysqlnd 5.0.8
ドキュメントルートにRoundcubeを入れておくと、こちらから設定が確認できるようです。
http://localhost/roundcube/installer/
設定出来ていれば”OK“の表示が!!
次にtemp、logsフォルダに書き込み権限を付与します。
設定方法は、こちらに詳しく書いてありました。
http://technet.microsoft.com/ja-jp/windows/ff189334.aspx
php.iniを編集
RoundCubeを動作させるために”php.ini”の内容を一部変更します。
//先頭の;を外す
extension=php_fileinfo.dll
//先頭の;を外す
extension=php_openssl.dll
私の場合、”php.ini”内に”extension=php_fileinfo.dll”の記述がなく
書いてるのと違う!どうしてくれんだ!!と焦りましたが
ちゃんと存在しました(;´∀`)
拡張モジュールは”php”フォルダの中の”ext”に収められています。
私の環境ではココです。
C:/PHP/ext
“php.ini”に”extension=php_openssl.dll”の記述を追加し、
設定を反映させるため、保存完了後、Apacheを再起動します。
Roundcubeに利用するデータベースを作成
私はphpmyadminを使用しました。
以下手順です。
1、WEBブラウザでhttp://localhost/phpmyadmin/にアクセスします
2、上部の”SQL”タブをクリックします
3、”サーバ上でクエリを実行する”に以下のコマンドを入力します
-- データベースの追加(データベース'roundcubemail'をUTF-8で作成)
CREATE DATABASE roundcubemail DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
-- ユーザの追加(ユーザ'roundcube@localhost'をパスワード'roundcube'で作成)
CREATE USER 'roundcube'@'localhost' IDENTIFIED BY 'roundcube';
-- アクセス権限の追加(データベース'roundcubemail'に対してユーザ'roundcube@localhost'に適用可能な権限すべてを一度に付与)
GRANT ALL PRIVILEGES ON roundcubemail.* TO roundcube@localhost IDENTIFIED BY 'roundcube';
4、右下の”実行”をクリックします
5、特に問題がなければ、”SQL は正常に実行されました”と表示されます
テーブルを作成
データベーステーブルを作成します。
以下手順です。
1、左部のデータベース一覧から”roundcubemail”を選択
2、上部”インポート”タブを選択
3、以下のファイルを読み込む
<ルートディレクトリ>/roundcube/SQL/mysql.initial.sql
インポートが完了すると、テーブルが12個新規作成されます。
Roundcubeの初期設定を行う
ここまで準備が整ったら、WEBブラウザ経由で以下のURLにアクセスし、初期設定を行います。
http://localhost/roundcube/installer/
動作するのに必須な項目が、すべて”OK“であれば問題無いようです。
最下部の”NEXT”をクリックして先に進みます。
それ以外の”NOT AVAILABLE“等になっている場合は、phpinfoを確認し、
コンポーネントが有効になっているか確認します。
設定は後からでも出来るので、特に何も設定しませんでした。
そのまま”CREATE CONFIG”をクリックすると、
main.inc.phpとdb.inc.phpの設定が、自動的に作成されます。
main.inc.php (download)
db.inc.php (download)
downloadをクリックして、それぞれ設定ファイルを
以下の場所に保存します。
<ルートディレクトリ>/roundcube/config
CONFIGファイルの編集
直接テキストエディタでファイルを編集します。
Gmailを利用した場合の設定です。
“main.inc.php”の設定
//IMAPサーバの指定
$rcmail_config['default_host'] = '';
↓
$rcmail_config['default_host'] = 'ssl://imap.gmail.com:993';
//IMAPサーバ接続ポートの変更
$rcmail_config['default_port'] = 143;
↓
$rcmail_config['default_port'] = 993;
//SMTPサーバの指定
$rcmail_config['smtp_server'] = '';
↓
$rcmail_config['smtp_server'] = 'ssl://smtp.gmail.com';
//SMTP接続ポートの変更
$rcmail_config['smtp_port'] = 25;
↓
$rcmail_config['smtp_port'] = 465;
//SMTPログインユーザの指定
$rcmail_config['smtp_user'] = '';
↓
$rcmail_config['smtp_user'] = '%u';
//SMTPパスワードの指定
$rcmail_config['smtp_pass'] = '';
↓
$rcmail_config['smtp_pass'] = '%p';
“db.inc.php”の設定
//SMTPパスワードの指定
$rcmail_config['db_dsnw'] = 'mysql://roundcube:pass@localhost/roundcubemail';
↓
//データベースのユーザ名とパスワードを入力
$rcmail_config['db_dsnw'] = 'mysql://root(ユーザ名):******(パスワード)@localhost/roundcubemail';
RoundCubeにログインする
http://localhost/roundcube/ にアクセスすると、RoundCubeのTOPページが表示されます。
ここで指定するログイン名は、実際のメールサーバのユーザー名とパスワードになります。
Gmailアカウントでログインする場合にはユーザー名にメールアドレス(xxxx@gmail.com)と、
パスワードを入力します。
問題なくログインできたら、不要になったinstallerフォルダの削除を行います。
以下を、フォルダごと削除して下さい。
<ルートディレクトリ>/roundcube/installer
以前試みた時には、うまくいかず断念しましたが、今回はなぜかスムーズに進みました。
大したことはしてませんが、動いてる感があるのでなんだか嬉しいです!
オリジナル感を出したいのでマークをねこちゃんに(笑)
可愛い可愛い(´∀`)ふふふ
スキンを自分好みに変えれるのは嬉しいですね~。
次は、プラグインを入れていきたいと思います。
Eサイクルがやってきた
『CEATEC JAPAN 2012』長崎県ブースに一緒に出展した有安オートさんのEサイクル「ISOLA」。
一目惚れして即発注でした。
本日、ついにやって来ました。折りたたみにパワーアップして!
折りたたんだ状態はこんな感じ。
組み立てた状態のは私(murave)の、折りたたみ状態のはminemazさんのです。
有安オートさんのページ
https://sites.google.com/site/ariyasuauto/
Eサイクル「ISOLA」のページ
http://www.isola-japan.com/
いらっしゃいませ OSC2012福岡
ブースこんな感じです。エレベーターで上がってきたらすぐというナイスポジション。
「受付ですか?」と言われガチなのがたまに傷デス。
あと喫煙所(屋上?)へもウチのブースの横から出れますヨ。
セミナー関係は14時からは @minemaz が
『県庁並行稼働中!OpenCOBOL汎用機ダウンサイジングでのハマりどころ』
というセミナーを行います。
また、12時からの
『OSS九州サミットあげいん ~横の連携、深めていきますよぉ~』
にも @minemaz がパネリストとして登場します。
よろしくお願いします。
おまけ。缶バッチ((C)みさくらなんこつ・JACUG)に侵略された自由配布ブース。
福岡Ruby会議01 その後の話
先週の土曜日、福岡Ruby会議01に参加しました。とても、とても刺激的な一日でした。
@Spring_MT さんがきれいにまとめてくださってます。
福岡Ruby会議01を開催 & トークしてきました! – CubicLouve
当日の話はそちらを見てもらったほうが良いなぁと思ったので個人的なその後の話を。
レールにのってて大丈夫か?
@kakutaniさんの話に出てきた札幌Ruby会議2012での@ursmさんの発表「Ruby on Rails: The Bad Parts」が気になったので動画を見ました。とても良かったです。
RailsやRailsっぽいWebフレームワークを扱っている人は見るべきだと思います。
ウチでもRubyでフィジカルコンピューティング
山崎さんのLT「Rubyでフィジカルコンピューティング」
最後のページにこうありましたね
「実験協力者募集中!」
てなわけで長崎代表として借りてきました BeagleBone!
先ほど山崎さんが作成されたディスクイメージで起動して設置しました!
いまのところ順調にログがとれているそうです。どんなデータがとれるか楽しみ!
OpenCOBOLとファイル操作(弊社拡張)
OpenCOBOLからのファイル操作ですが内部での定義によって幾つか種類があります。
- 固定長レコードのシーケンシャルファイル
- 固定長レコードのISAM形式ファイル
- 可変長レコードのシーケンシャルファイル
- 他
これらはCOBOLソース内でのSELECT句での定義でファイル名を直接または環境変数を経由して間接的に指定することが可能です。OpenCOBOLの素の状態ですと
SELECT ADBF0320 ASSIGN TO "FILE0001"
ORGANIZATION SEQUENTIAL
ACCESS MODE SEQUENTIAL.
と記述されている場合は、FILE0001または環境変数 DD_FILE0001または dd_FILE0001に設定されているファイル名のファイルのOPENが可能です。弊社ではこの環境変数渡しの機能を活用してperlからOpenCOBOL側へJCL中で使用しているファイル名を渡しています。
さて、JCL中ではSYSINと呼ばれる形式でファイルを作らずにその場で渡したいデータを記述することがあります。
\INPUT ACCEPT1,TYPE=DATASSF,LIST=YES
4241122 登録データ1
4241122 登録データ1追加分
\ENDINPUT;
ADAM2200:
\STEP PROG2000 FILE=USL.CAT1 DUMP=DATA SUBLM=NORMAL;
\ASSIGN FILE0010 USR.F001 SHARE=ALL HOLDMODE=NO;
\ASSIGN FILE0110 USR.F011-T FILESTAT=TEMP PUBLIC NORMAL=PASS;
\ALLOCATE FILE0110 USR.F011-T SIZE=05;
\DEFINE FILE0110 RECSIZE=57 BLOCKSZ=10260 INCRSZ=01
RELSP RECFORM=FB;
\ASSIGN SIN ACCEPT1 FILESTAT=SYSIN;
\ENDSTEP;
上記ではJCL中で定義されたASSIGN1というSYSINの内容をSINというファイル識別名に割り当てています。これをperlに置き換える(この部分自動的に処理しています)と
INPUT "ACCEPT1,TYPE=DATASSF,LIST=YES",<<_EOT;
4241122 登録データ1
4241123 登録データ1追加分
_EOT
ENDINPUT;
ADAM2200:
STEP "PROG2000 FILE=USL.CAT1 DUMP=DATA SUBLM=NORMAL";
ASSIGN "FILE0010 USR.F001 SHARE=ALL HOLDMODE=NO";
ASSIGN "FILE0110 USR.F011-T FILESTAT=TEMP PUBLIC NORMAL=PASS";
ALLOCATE "FILE0110 USR.F011-T SIZE=05";
DEFINE "FILE0110 RECSIZE=57 BLOCKSZ=10260 INCRSZ=01",
"RELSP RECFORM=FB";
ASSIGN "SIN ACCEPT1 FILESTAT=SYSIN";
上記のように変換しています。さて、SYSINの内容ですがまず1レコードが何byteであるという情報がありません。そして1行毎に行の長さが異なっています。今回移植の対象となった対象機のCOBOLではこのような場合には「改行区切りで1レコード」とするようになっていました。つまり可変長レコードです。ところがOpenCOBOLで可変長レコードをファイルとして扱うためには:
レコード先頭1バイトまたは2バイトにレコード長+1レコード分のデータ
レコード先頭1バイトまたは2バイトにレコード長+1レコード分のデータ
・・・
という形式でデータを作成する必要があります(つまり1byte目がレコード長として正しくないと、メモリ上に過大な長さのデータが読み込まれて、あっという間にSegfault します)。OpenCOBOLの外側からファイルの形式について何らかの方法で指示を出す必要が在りましたので、弊社ではファイル名の先頭に「sysin://」という識別子を(URI的に)付けてファイル名を渡すようにしています。これをOpenCOBOL内のファイルハンドラに渡る前に処理し、改行区切りの可変長レコードとして処理しています。同じく、印刷用の中間データなど1行の長さが可変長となる場合について「sysout://」という識別子を付けて指定することができるようにしています。他、標準の固定長レコードのドライバと動作をちょっと変えたドライバを使いたい場合を考え「misam://」や「mseq://」さらにLinux他では/dev/nullに該当するものとして「nullfs://」という識別子を指定可能としています。
標準の固定長レコードのドライバと動作をちょっと変えたいというのは例えばレコード挿入、削除時の細かい振る舞い、二次キー指定時の動作、二次キーを持っているISAMファイルを主キーしか定義していないCOBOLソースから書き込みモードで開いた場合の動作(OpeCOBOLの標準の動作では、書き込みモードでISAMファイルを開くと、一旦削除されますので、最悪二次キーについての定義が欠落します)等々です。
また、「perlfs://CLASSNAME/param」という形式でファイル名を渡す事によりファイルハンドラとしてperlにて記述したものを呼び出すようにもしています。DBとCOBOL内の固定長レコードの編集用コードについてperlで記述できるため、大変柔軟にDBとの連携を図れるようになりました(つまり、DBD::PgやDBD:MySQL、Oracleなどとの連携も可能です。MySQLについては既に運用されていますし、KeyValue系のDBへの接続もそれほどの変更なしに実装できます)。
上記に加え、固定長レコードやキー定義などの情報を別ディレクトリ内の管理ファイルに登録しておくことで、ファイルオープン時に正しい形式のファイルを使用しているかどうかCOBOLプログラム内の定義と照らし合わせて動的にチェックできるようになり、また現在どのようなファイルがオープン状態であるか?を全てモニタできるようにしています。
これらの改造はOpenCOBOLがオープンソースとして配布されていたことで可能になりました。成果は随時コミュニティ等にフィードバックしていきたいと考えております。
Androidで影を描いてみる。
ずっと前からブログのネタとして暖めていた、Androidで影を描く方法を書きたいと思います。
先に書いたソースを載せます。
import android.content.Context;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.View;
public class ShadowView extends View {
private Paint white = null;
private Paint black = null;
private Paint shadow = null;
private RectF rect = null;
private RectF shadowRect = null;
public ShadowView(Context context) {
super(context);
white = new Paint();
white.setColor(Color.WHITE);
white.setAntiAlias(true);
black = new Paint();
black.setStyle(Paint.Style.STROKE);
black.setAntiAlias(true);
shadow = new Paint();
shadow.setStyle(Paint.Style.FILL);
shadow.setColor(Color.argb(112, 0, 0, 0));
BlurMaskFilter blur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
shadow.setMaskFilter(blur);
rect = new RectF(50f,100f,250f,200f);
float diff = 30f;
shadowRect = new RectF(50f + diff,100f + diff,250f + diff,200f + diff);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//背景を描画
drawBackground(canvas);
//角丸の矩形の影
canvas.drawRoundRect(shadowRect, 50, 50, shadow);
//角丸の矩形の背景(白)
canvas.drawRoundRect(rect, 50, 50, white);
//角丸の矩形の枠線(黒)
canvas.drawRoundRect(rect, 50, 50, black);
}
/**
* 背景を描画
* @param canvas
*/
private void drawBackground(Canvas canvas){
Paint paint = new Paint();
paint.setColor(Color.rgb(214, 233, 255));
int height = getHeight();
int width = getWidth();
int y = 0;
while(y
2)それを右下にずらした矩形を作ります。
右下に30ずらしてます。
rect = new RectF(50f,100f,250f,200f);
↓
float diff = 30f;
shadowRect = new RectF(50f + diff,100f + diff,250f + diff,200f + diff);
なんか書いてみたら、ずっと暖めていた割に簡単だった・・。
暖めすぎたか・・。
ポイントは、影のペイントは、ぼかし効果をいれるところです。
BlurMaskFilter blur = new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL);
OpenCOBOLとSPECIAL-NAMES(拡張)
JCLからCOBOLを呼び出す際に外部パラメータを渡したいということがあります。某社JCLでは
\DCV ACCEPT2,CHARACTER='04' ;
などDCVというコマンドで定義して、これをCOBOL側では
SPECIAL-NAMES.
CHAR002 IS ACCEPT2.
のように記述して取り込んでいるようです(この場合CHAR002に’04’が入ります)。
ところがもちろんOpenCOBOLにはこのような機能はありません。実際 SPECIAL-NAMES. 部分の定義をcobc/parser.yから拾い上げると:
special_name:
mnemonic_name_clause
| alphabet_name_clause
| symbolic_characters_clause
| locale_clause
| class_name_clause
| currency_sign_clause
| decimal_point_clause
| cursor_clause
| crt_status_clause
| screen_control
| event_status
;
となっており、mnemonic_name_clause 部分が使えそうなのですが、system_nameとして使用できるのは
} system_table[] = {
{"SYSIN", CB_DEVICE_NAME, CB_DEVICE_SYSIN, NULL},
{"SYSIPT", CB_DEVICE_NAME, CB_DEVICE_SYSIN, NULL},
{"SYSOUT", CB_DEVICE_NAME, CB_DEVICE_SYSOUT, NULL},
{"SYSLIST", CB_DEVICE_NAME, CB_DEVICE_SYSOUT, NULL},
{"SYSLST", CB_DEVICE_NAME, CB_DEVICE_SYSOUT, NULL},
{"PRINTER", CB_DEVICE_NAME, CB_DEVICE_SYSOUT, NULL},
{"SYSERR", CB_DEVICE_NAME, CB_DEVICE_SYSERR, NULL},
{"CONSOLE", CB_DEVICE_NAME, CB_DEVICE_CONSOLE, NULL},
{"C01", CB_FEATURE_NAME, CB_FEATURE_C01, NULL},
{"C02", CB_FEATURE_NAME, CB_FEATURE_C02, NULL},
{"C03", CB_FEATURE_NAME, CB_FEATURE_C03, NULL},
{"C04", CB_FEATURE_NAME, CB_FEATURE_C04, NULL},
{"C05", CB_FEATURE_NAME, CB_FEATURE_C05, NULL},
{"C06", CB_FEATURE_NAME, CB_FEATURE_C06, NULL},
{"C07", CB_FEATURE_NAME, CB_FEATURE_C07, NULL},
{"C08", CB_FEATURE_NAME, CB_FEATURE_C08, NULL},
{"C09", CB_FEATURE_NAME, CB_FEATURE_C09, NULL},
{"C10", CB_FEATURE_NAME, CB_FEATURE_C10, NULL},
{"C11", CB_FEATURE_NAME, CB_FEATURE_C11, NULL},
{"C12", CB_FEATURE_NAME, CB_FEATURE_C12, NULL},
{"FORMFEED", CB_FEATURE_NAME, CB_FEATURE_FORMFEED, NULL},
{"SWITCH-1", CB_SWITCH_NAME, CB_SWITCH_1, NULL},
{"SWITCH-2", CB_SWITCH_NAME, CB_SWITCH_2, NULL},
{"SWITCH-3", CB_SWITCH_NAME, CB_SWITCH_3, NULL},
{"SWITCH-4", CB_SWITCH_NAME, CB_SWITCH_4, NULL},
{"SWITCH-5", CB_SWITCH_NAME, CB_SWITCH_5, NULL},
{"SWITCH-6", CB_SWITCH_NAME, CB_SWITCH_6, NULL},
{"SWITCH-7", CB_SWITCH_NAME, CB_SWITCH_7, NULL},
{"SWITCH-8", CB_SWITCH_NAME, CB_SWITCH_8, NULL},
{NULL, 0, 0, NULL}
};
上記以外の場合は”Unknown system-name ‘何々'” のメッセージが出力されてエラーとなります。弊社にて対応した際、当初は外部からの値を環境変数経由で渡す事を検討しましたが、COBOL内部で値をセットしてJCLへ返す場合があると言うことで思い切って機能拡張しました。DCVにて渡された値については環境変数(DCV_varname=値)を定義して渡し、値を書き替える場合も環境変数を書き替え、プロセス終了時にDCV_varname環境変数の値を全てファイルへ書き出しています。書き替えた値をJCLへ返す際にこの(環境変数 SYSTEM_STATUS_FILE に定義されたファイル名の)ファイルを読み込んでいます。
これらの拡張とJCLをperlに変換した*.jclスクリプトを使用することで DCV機能は
DCV "ACCEPT2,CHARACTER='04'";
という記述のperlスクリプトと
SPECIAL-NAMES.
CHAR002 IS ACCEPT2.
元のCOBOLプログラムをそのまま解釈できる拡張したOpenCOBOLにて処理できるようになりました。移植対象のコード中にDCVを使用している箇所が4桁箇所以上もありましたが、かなり簡単に移植ができました。
OpenCOBOLで印刷機能拡張(コード側)
OpenCOBOL-1.1は印刷に関しては改行または改ページ程度しかケアしてくれません。そのままでは業務では使いづらいので色々と拡張して弊社では使っています。印刷機能というとREPORT caluse でREPORT IS hogeなどで定義して使うのが一般的ですが、このあたりは各社拡張しているようです。
弊社で対応した先では、定義にCHARACTER TYPE fontname COLUMN pos 形式で書ける拡張がされていましたのでcobc/parser.y 他に手を入れて同様の構文が処理できるように拡張しています(つまり、元の汎用機機種のCOBOLソースによってはそのままコンパイルが通ります)。
02 FILLER PIC N(13) CHARACTER TYPE KM-12P
VALUE "ダンプリスト" .
02 FILLER PIC X(14) VALUE SPACE.
02 FILLER PIC N(04) CHARACTER TYPE KM-7P
VALUE "作成日" .
02 H01-YY PIC Z9.
02 FILLER PIC N(02) CHARACTER TYPE KM-7P
VALUE "年 " .
02 H01-MM PIC Z9.
02 FILLER PIC N(02) CHARACTER TYPE KM-7P
VALUE "月 " .
上記ではKM-7PまたはKM-12Pというフォント名で対応する文字列を印字するように定義されています。
また、
01 W-WORK.
02 W-SEIRNO PIC ZZZZZZZ9 COLUMN 4.
02 W-YMD PIC X(08) COLUMN 13.
02 W-KIN PIC ZZZZ,ZZZ,ZZZ,ZZ9 COLUMN 22.
上記では印字位置を COLUMNで指定しています。
さて、これらを内部的にどのように処理しているのかと言いますと、当初(2010〜2011年頃)取りかかった頃は文字フォント指定や文字位置指定をコンパイル中に「隠れFILLER」として定義を埋め込んでいたのですが、GROUP項目をMOVEするときにサイズが異なってしまうという問題にあたりました。そこで、WRITE時にCHARACTER TYPEまたはCOLUMNに対応する情報にしたがって別のバッファに値を詰め直すようにしています。これは印刷に係わる出力へのWRITE時だけ効くようにしていますので、通常のMOVE時や印刷に関連しない出力では影響を受けないようになっています。
この印刷機能は印刷用のWRITEを呼び出す前に、以下の様な関数を呼び出すことで実現しており、この関数は元の印刷定義にしたがってコンパイル時に自動生成されています。
cob_move_with_W_WORK (cob_field *from, cob_field *to, const int size)
{
unsigned char *fp = from->data;
unsigned char *tp = to->data;
unsigned int i1 = 0;
unsigned int i2 = 0;
unsigned int i3 = 0;
// name= W-SEIRNO
memcpy(tp, "\x1b[4G", 4);
tp += 4;
memcpy(tp, fp, 8);
tp += 8;
fp += 8;
// name= W-YMD
memcpy(tp, "\x1b[13G", 5);
tp += 5;
memcpy(tp, fp, 8);
tp += 8;
fp += 8;
// name= W-KIN
memcpy(tp, "\x1b[22G", 5);
tp += 5;
memcpy(tp, fp, 16);
tp += 16;
fp += 16;
// 以下略
「\x1b [ col G」のようなエスケープシーケンス(多分若い人はご存じない?)を印刷出力用の中間データに吐き出すことで「colカラム目に移動」のような指示を仮想ラインプリンタ(PDF出力用)に送り出しています。仮想ラインプリンタ側ではこのようなエスケープシーケンス以外にも、プリンタのカーソル位置を直接指定するようなバイナリコードにも対応させましたので、印刷帳票に関連するCOBOLプログラムの移植についてかなり柔軟に対応出来るようになりました。
そして、「何行出力したら改ページ」「データが続いていたら連続出力、変わったら改ページ」のような印刷帳票にありがちな処理についてロジックに手を入れること無くそのまま移植出来てしまうと言う利点があり、COBOLで帳票を利用しているプログラムの移植にお困りの方には大変有用なソリューションだと思います。