ページへ戻る

− Links

 印刷 

GUIGUI01​/memo27 のバックアップソース(No.1) :: OSASK計画

osaskwiki:GUIGUI01/memo27 のバックアップソース(No.1)

  Next »[4]
* ぐいぐい01に関するメモ-27
-(by [[K]], 2009.01.13)
-メモのうち重要な部分をそのうちまとめてまともなページを作る
*** (39) GOで「ぐいぐい01」アプリを作る(5)
-[[GUIGUI01/memo26]]の続きです。
----
-今回の最初のプログラムは、いわゆるファイルダンプです。ファイルをオープンして、それを16進数でだだーっと書きます。ex0021.cです。
 #include <guigui01.h>

 unsigned char cmdusage[] = {
     0x86, 0x50,
     0x01, 'i', 'n', 0x0c, 9, 0x01, 'p', 'u', 't', '-', 'f', 'i', 'l', 'e',
     0x40
 };

 void sethex(char *s, int i, int n)
 {
     int j;
     for (j = n - 1; j >= 0; j--) {
         s[j] = '0' + (i & 0xf);
         i >>= 4;
         if (s[j] > '9') {
             s[j] += 'A' - '0' - 10;
         }
     }
     return;
 }

 void G01Main()
 {
     unsigned char buf[16];
     int i = 0, j;
     g01_setcmdlin(cmdusage);
     g01_putstr0(" offset   +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F  0123456789ABCDEF\n");
     g01_putstr0("---------------------------------------------------------------------------\n");

 }
-ex0016では、cmdusage[ ]が合計18バイトにまで増えました。しかしこれは13バイトにまで減らせます。小さいことは「ぐいぐい01」ではとても重要なことなので、最初はそれを説明しようと思います。
-ex0016のcmdusage[ ]の中には、16進数の1の位に「c」が出てくる場所が5ヶ所あります。これは、gh4のコードで「次の1バイトを数値として解釈」させるために使っています。しかし、もし値が0~4の範囲であれば、わざわざこんなことしないで、「c」の位置にその値を直接書いてしまっていいのです。gh4とはそういうものなのです。
//ちなみに最初の 0x86, 0x5c, ?, の「c」の部分は4までしか置き換えられませんが、その他の「c」は5もOKです。
-何を言っているのかよく分からないと思いますが、たとえば、
 0x86, 0x5c, 0,
-の部分を考えましょう。これは、
 0x86, 0x50,
-と短く書けるのです。これで1バイト節約できます。同じようにして、他の部分を全部整理するとこうなります。ex0017.cです。
 #include <guigui01.h>

 unsigned char cmdusage[] = {
     0x86, 0x50,
     0x00, 's', 0x33, 's', 't', 'r',
     0x10, 'n', 0x11, '#',
     0x40
 };

 void G01Main()
 {
     (ex0015.cと同じ内容)
 }
-これをmakeすると139バイトになります。でも動作はex0016と完全に同じです。
----
-じゃあもう一つ小さくする技を。ex0017では引数が「s:str」と「n:#」でしたが、これを「str:string」と「num:number」にしたいとしましょう。まあどうせ順序を覚えていれば「str:」や「num:」とタイプする必要はないですしね。それなら分かりやすいほうがいい、と考える人もいるでしょう。
--そういえば今まで説明してきませんでしたが、引数名は半角で文字コード0x21~0x7eの範囲で(つまり数字はいいけどスペースはダメ)、「"」や「:」を含まないものにしなければいけません。というか記号類は避けたほうがいいです。確実に使っても問題がない記号を以下に挙げておきますが、とにかく記号なんて使うと、OSによっては(というかシェルによっては)、入力しにくくなること請け合いです(後半のものはできれば使わないで置いたほうがいいんじゃないかと思ったもの)。
 !#'=~+-/@_\^`  ;?*&
-ということでex0018.cです。
 #include <guigui01.h>

 unsigned char cmdusage[] = {
     0x86, 0x50,
     0x02, 's', 't', 'r', 0x34, 0x01, 'i', 'n', 'g',
     0x12, 'n', 'u', 'm', 0x11, 0x01, 'b', 'e', 'r',
     0x40
 };

 void G01Main()
 {
     (ex0015.cと同じ内容)
 }
-ここでまたサイズを節約するテクニックを使いました。というのは引数説明のところで、0x01というのを使っているからです。これはusage表示するときに引数名に置換されます。これを使うことで 0x3c や 0x1c を使わずに済んでいますし、そもそも置換することでそれぞれ2バイト節約しています。
-makeすると147バイトになります。一応usage表示を見て確認しておきましょう。
 >efg01 ex0018.g01
 usage>ex0018.g01 [str:]string [[num:]number]
----
-こうしてコマンドラインにたくさん引数を使うようになると、usage表示がかなり長くなることがあります。「usageなんかみないぜ!そんなの気にしない」っていう人はそれで問題ないんですが、やっぱりどうせならきれいにusage表示してほしいって思う人もいるでしょう。ここではその方法を説明したいと思います。
-ということでex0019.cです。
 #include <guigui01.h>

 unsigned char cmdusage[] = {
     0x86, 0x50,
     0x02, 's', 't', 'r', 0x34, 0x01, 'i', 'n', 'g',
     0x87,
     0x12, 'n', 'u', 'm', 0x11, 0x01, 'b', 'e', 'r',
     0x40
 };

 void G01Main()
 {
     (ex0015.cと同じ内容)
 }
-これをmakeすると148バイトになりますが、注目ポイントは 0x87, です。これがあると、usage表示のときにここで改行します。それ以外の効果はありません。この改造をしてももちろん「num:」は引数番号1のままです(2になったりはしない)。
-これをusage表示させるとこうなります。
 >efg01 ex0019.g01
 usage>ex0019.g01 [str:]string
         [[num:]number]
----
-さてここまでで整数型引数と文字列型引数を紹介してきましたが、次はフラグ型引数を紹介します。これは値を指定するのではなく、単にその引数名が現れたかどうかだけを問題にします。・・・どんな例にしましょうか。じゃあたとえば0からnまで数えるプログラムを使いましょう。ex0020.cです。
 #include <guigui01.h>

 unsigned char cmdusage[] = {
     0x86, 0x51, /* フラグ型は自動当てはめ対象からははずすようにする */
     0x13, 'd', 'o', 'w', 'n', 0x20,
         /* フラグ型は当然省略可能に。そしてフラグ型には説明を付けない。 */
     0x00, 'n', 0x11, '#',
     0x40
 };

 void setdec(char *s, int i, int n)
 {
     (ex0010.cと同じ内容)
 }

 void G01Main()
 {
     int i, n;
     char s[4];
     g01_setcmdlin(cmdusage);
     n = g01_getcmdlin_int_s(1);
     if (g01_getcmdlin_flag_o(0) == 0) {
         /* down指定がない場合 */
         for (i = 0; i <= n; i++) {
             setdec(s, i, 3);
             s[3] = 0;
             g01_putstr0(s);
         }
     } else {
         /* down指定がある場合 */
         for (i = n; i >= 0; i--) {
             setdec(s, i, 3);
             s[3] = 0;
             g01_putstr0(s);
         }
     }
     return;
 }
-これをmakeすると265バイトになります。そしてusageを出してみると、こうなります。
 >efg01 ex0020.g01
 usage>ex0020.g01 [down] [n:]#
-適当に実行してみるとこんな感じです。
 >efg01 ex0020.g01 10
   0  1  2  3  4  5  6  7  8  9 10

 >efg01 ex0020.g01 7 down
   7  6  5  4  3  2  1  0
-プログラムから推測できるように、 0x2c がフラグ型になります。しかしフラグ型では説明は付けないので、 0x20 を使うことになります。フラグ型を指定するときは、「down:」のように末尾に「:」があっても構いません。
 >efg01 ex0020.g01 7 down:
   7  6  5  4  3  2  1  0
-フラグがコマンドライン中に存在していれば、g01_getcmdlin_flag_o()の値が0以外になります。存在しなければ0です。

* こめんと欄
- このシリーズは好評のようです。実際にアプリを作って遊んでくれる人も出てきました。 -- [[K]] &new{2009-01-13 (火) 11:07:16};

#comment

  Next »[4]