ページへ戻る

+ Links

− Comments

 印刷 

hideyosi​/hijk​/引数やUsage :: OSASK計画

osaskwiki:hideyosi/hijk/引数やUsage

guigui01の仕様の整理とかそういうの。

Page Top

複雑・・・ anchor.png

・・・解ってきたぞ。つまり、これは単なるUsage表示だけじゃなくて、このアプリのコマンドライン引数の定義も兼ねているのか・・・

#include <guigui01.h>

/* これは関数の外で宣言するのが望ましい */
unsigned char cmdusage[] = {
    0x86, 0x55, /* この2つは決まり文句なのでとりあえず変更しない */
    0x0c, 0, 'n', 0x1c, 1, '#', /* この説明は本文で */
    0x40 /* 最後のこれも決まり文句なので変更しない */
};

この設定で表示されるUsage。
usage>ex0012.g01 n:#

どうもUsage表示は関数化されているようだ。どうすれば自由にUsageが表示できるだろう・・・

Page Top

解析 anchor.png

0x86, 0x55これは頭に付ける決まり文句らしい。(でも0x50とかが確認されている)
0x0c, 0, 'n', 0x1c, 1, '#',これらはコマンドになるらしい
0x40お尻につける決まり文句

どうもこれでワンセットになるらしい。

0x0c(引数名の文字数-1)(引数名)0x1c(説明部分の文字数)(説明)

たとえば上の例だと・・・

0x0cコマンド 
(引数名の文字数-1)0引数名はn。一個。 1 - 1 = 0
(引数名)'n'一個しか置けない。
0x1cコマンド 
(説明部分の文字数)1説明は一文字だけなので1?
(説明)'#' この#一文字が説明ってことかな??
Page Top

実験的に逆に考えてみる・・・ anchor.png

この部分はUsageを表示するんじゃなくて、そもそもコマンドライン引数を定義すると。

で!

この定義に沿って、自動的にUsageメッセージを作って表示してくれると!

Page Top

引数先頭のコマンド anchor.png

0x86, 0x55通常モード
0x86, 0x5c, 0引数名省略可能モード

http://osask.net/w/264.html

省略が可能。

上記 0x86, 0x5c, 0 は、 0x86, 0x50 と縮めて書くことができる。

おそらく、0x5x の一桁目が合成できるってことだろう

Page Top

省略できない引数 anchor.png

省略したり順番が違うとエラーになってほしい引数

0x0c(引数名の文字数-1)(引数名)0x1c(説明部分の文字数)(説明)
これは省略不可の引数だというサインこの引数は数値であるというサイン
合成が可能。コマンドの一桁目を引数名の文字列-に置き換える 合成が可能。コマンドの一桁目を引数名の文字列-に置き換える 
Page Top

省略可能な引数 anchor.png

省略することもある引数

0x1c(引数名の文字数-1)(引数名)0x1c(説明部分の文字数)(説明)
これは省略可能な引数だというサインこの引数は数値であるというサイン
  • Usage表示では自動的に [ ] で括られて表示される
Page Top

引数が文字列の場合 anchor.png

0x0c, 0, 's', 0x3c, 3, 's', 't', 'r', /* 0x3cは文字列型引数 */
0x0c(引数名の文字数-1)(引数名)0x3c(説明部分の文字数)(説明)
これは省略不可な引数だというサインこの引数は文字列だというサイン
Page Top

引数がファイルパスである場合 anchor.png

0x0c, 1, 'i','n', 0x3c, 10, 'i', 'n', 'p','u','t','-','f','i','l','e' /* 0x0cはファイルパス型引数 */
0x0c(引数名の文字数-1)(引数名)0x0c(説明部分の文字数)(説明)
これは省略不可な引数だというサインこの引数はファイルパスだというサイン
Page Top

超省略形 anchor.png

  • [in:]input-file の形でかまわないなら、 単に 0x88と書けばいい。
  • ↑と同じで、さらに省略可能形式なら、0x89と書けばいい。
Page Top

説明時に引数名の文字列を使う anchor.png

引数名はよく略称を使われる。たとえば、文字列(string)の引数がほしい場合は、

str:

なんてのを使う。Usageでは、str:引数の後の説明は当然、

str:string

になる。(つまり、s と t と r がかぶっている。)

普通にUsage表示(コマンドライン定義)をしたい場合は、

0x0c, 2, 's', 't', 'r', 0x3c, 6, 's', 't', 'r', 'i', 'n', 'g'

となるが、文字が勿体ない場合、0x01 を置くと前で定義した引数名(「str」)に置換してくれる。

ただし注意。上記のようにベタに書くと「string]は6文字なので6を指定しているが、置換を使う場合は残りの文字数+1になる。(つまり0x01で一文字)

0x0c, 2, 's', 't', 'r', 0x3c, 4, 0x01, 'i', 'n', 'g'
Page Top

改行 anchor.png

0x87,
Page Top

スイッチ anchor.png

引数ではなくスイッチ?な場合。

0x1c, 3, 'd', 'o', 'w', 'n', 0x20,
0x1c3'd', 'o', 'w', 'n'0x20
省略可能なオプションであるサインdownなので、4-1で3スイッチには引数内容がないのでそのサイン
Page Top

引数の受け取り anchor.png

getcmdline系で受け取るらしいんだけど、どうもわからん。例えばこんなことして・・・

unsigned char cmdusage[] = {
  0x86,  /* これは決まり文句なのでとりあえず変更しない */
  0x55,  /* 引数名省略可能モード */

  0x1c, 2, 'o','p','t', 0x0c, 9, 0x01, 'i', 'o', 'n', '-', 'f', 'i', 'l', 'e',
  0x0c, 2, 'o','u','t', 0x0c, 9, 0x01, 'p', 'u', 't', '-', 'f', 'i', 'l', 'e',

  0x40 /* 最後のこれも決まり文句なので変更しない */
};

第一引数をプログラム内に受け取るにはどうしたらえぇんじゃろ・・・見つからないなぁ・・・

関数で、戻り値があるのかないのかは、guiguo01.h内を見ればわかるらしい。strct inlune int なんてやってるのは、int型の戻り値を持つもの!・・・だと思う。多分・・・

引数をプログラム内に受け取ると思われる関数は以下のとおり。

  • Void g01_getcmdlin_exit1()
  • Void g01_getcmdlin_fopen_s(i)
  • Void g01_getcmdlin_fopen_o(i)
  • Void g01_getcmdlin_fopen_m(i, j)
  • Void g01_getcmdlin_fopen_s_0_4(i)
  • Void g01_getcmdlin_fopen_s_3_5(i)
  • int g01_getcmdlin_fopen_m_0_4(int i, int j)
  • int g01_getcmdlin_fopen_o_0_4(int i)
  • int g01_getcmdlin_fopen_o_3_5(int i)
  • int g01_getcmdlin_flag_s(int i)
  • Void g01_getcmdlin_flag_o(i)
  • Void g01_getcmdlin_int_s(i) あっれえぇ?これはdevineなのに戻り値があるはず? 法則がわからん・・・
  • int g01_getcmdlin_int_o(int i, int d)
  • Void g01_getcmdlin_str_s0(i, n, p)
  • Void g01_getcmdlin_str_s0_0(n, p)
  • int g01_getcmdlin_str_o0(int i, int n, void *p)
  • int g01_getcmdlin_str_m0_1(int j, int n, void *p)
  • int g01_getcmdlin_argc(int i)
  • Void g01_getcmdlin_put0_s(i)
  • Void g01_getcmdlin_put1_s(i)
  • Void g01_getcmdlin_put0_m_exit1(i, j)
  • Void g01_getcmdlin_put1_m_exit1(i, j)
  • int g01_cmdlin3s(int l) {}
  • int g01_cmdlin3m(int l, int i) {}
  • int g01_cmdlin4s(int l) {}
  • int g01_cmdlin4m(int l, int i) {}
  • int g01_cmdlin5s(int l) {}
  • int g01_cmdlin5m(int l, int i) {}
  • int g01_cmdlin6s1(int l, int n, void *p) {}
  • int g01_cmdlin6m1(int l, int i, int n, void *p) {}
  • Void jg01_getcmdline0
  • Void jg01_getcmdline1
  • int jg01_getcmdlin0(int n, void *p)
  • Void jg01_getcmdlin1(n, p)
Page Top

引数受け取り関数の整理(予測ね。実験しながら・・・) anchor.png

引数には、定義した順に0から番号が付いているらしい。

  • int g01_getcmdlin_argc(int 引数番号)
    • 指定した番号の引数があるかないか。あれが1、なければ0を返す
      たとえばこういう設定をしたとする。
      unsigned char cmdusage[] = {
        0x86,  /* これは決まり文句なのでとりあえず変更しない */
        0x55,  /* 引数名省略可能モード */
      
        0x1c, 2, 'o','p','t', 0x0c, 9, 0x01, 'i', 'o', 'n', '-', 'f', 'i', 'l', 'e', ←引数番号0
        0x0c, 2, 'o','u','t', 0x0c, 9, 0x01, 'p', 'u', 't', '-', 'f', 'i', 'l', 'e',  ←引数番号1
      
        0x40 /* 最後のこれも決まり文句なので変更しない */
      };
      
      ↓Usage表示(コマンドラインの設定)はこうなる。
      usage>test.g01 [opt:option-file] out:output-file

このプログラム内で

int i; i = g01_getcmdlin_argc(0);

こんなことしたとする。引数を付けて実行してみると・・・

>hijk.exe test.g01 opt:hogehoge.txt out:ugougo.txt
 i=1                                                    ←0番目の引数が存在するぞ!

>hijk.exe test.g01 out:ugougo.txt
 i=0                                                    ←0番目の引数は指定されてない(空)だぞ!

・・・・・こういうことでいいのかな・・・・・

たとえばこの例だと、0番引数optは、「もし指定があればそのファイル名を使え。でもなければ、ディフォルトのosalink1.optを使用してくれ」という動作をさせたい。とういう場合は・・・

int i;
i = g01_getcmdlin_argc(0);
if( i == 0 ) {
     g01_fopen(1,4,"osalink1.opt");
}else {
     g01_fopen(1,4,getcmdlinexxxxxxx);
}

こういう処理をしてあげればいい・・・のかな・・・(これ合ってるかな)

Page Top

ファイル名取得&オープン系 anchor.png

まいったなこんなにあるよ・・・どれがどれだがよくわからん・・・

  • g01_getcmdlin_fopen_s(i)
  • g01_getcmdlin_fopen_o(i)
  • g01_getcmdlin_fopen_m(i, j)
  • g01_getcmdlin_fopen_s_0_4(i)
  • g01_getcmdlin_fopen_s_3_5(i)
  • g01_getcmdlin_fopen_m_0_4(int i, int j)
  • g01_getcmdlin_fopen_o_0_4(int i)
  • g01_getcmdlin_fopen_o_3_5(int i)

各関数のfopenの後ろの文字の意味。

  • o
    • オプショナル型ということらしい。省略可能なものを扱うものらしい。
  • s
    • シングル型。通常型らしい。つまり省略可能ではないものの場合に使う・・・のかな?
Page Top

getcmdlin分類 anchor.png

ダメだ・・・ちょっと分類を組み立てなおし!

  • g01_getcmdlinは引数をプログラム内に受け取る関数郡。
Page Top

g01_getcmdlin_int系 anchor.png

数字タイプの引数を受け取るもの。(intなので多分int型変数の制限を受けると思う。0~4294967295 or -2147483648~2147483647 とかの。)

Page Top

g01_getcmdlin_int_s系 anchor.png

省略不可(普通?シングル型というらしい)の引数を取得する。省略不可なのだから、指定がなかったりすればエラーとなる(・・・はず・・・)

int g;                           ←引数を受け取る変数
int i; i = 0;                    ←引数番号を指定する。0なので、一番最初に定義された引数
g = g01_getcmdlin_int_s(i);      ←問題なければgに引数の内容が入る
  • g01_getcmdlin_int_s(i)
Page Top

g01_getcmdlin_int_o系 anchor.png

省略可能(オプショナル型というらしい)の引数を取得する。省略可能なのだから、指定がなかったりしてもエラーにならない

省略された場合の規定値が必要になる。第二引数の int d がこれを担当する。

int g;                               ←引数を受け取る変数
int i; i = 0;                        ←引数番号を指定する。0なので、一番最初に定義された引数
g = g01_getcmdlin_int_o(i,100);      ←問題なければgに引数の内容が入る。
                                       もしこの引数が指定されてなかった場合は、100が指定された
                                      (規定値)とみなしてgに100が返される。
  • g01_getcmdlin_int_o(int i, int d)
Page Top

g01_getcmdlin_str系 anchor.png

文字列型のデータを受け取る。

Page Top

g01_getcmdlin_str_s0系 anchor.png

シングル型。省略不可の引数の場合に使う。(s0となっているのは「文字列として受け取り、末尾に0をつけるという働きのためだと思われる。

戻り値を持たないことに注意!

int i; i = 0;                             ←取得する引数番号
int n; n = 16;                            ←取得する文字列の最大長(この場合は16バイト分)
char s[16];                               ←取得した引数(文字列)を格納する配列orポインタ

g01_getcmdlin_str_s0(i, n, s)             ←戻り値なし。引数がs[]に格納され、末尾に0が付く
  • g01_getcmdlin_str_s0(i, n, p)
  • g01_getcmdlin_str_s0_0(n, p)

ダメダ・・・これも規定値の扱いがわからん・・・・

  • g01_getcmdlin_str_o0(int i, int n, void *p)
  • g01_getcmdlin_str_m0_1(int j, int n, void *p)

うっちゃんの予測を検証すべく、実験をしてみた

ちなみにオイラの予想してたこと。intタイプと同じように、コード内に規定値を打ち込むような形式だと思ってた

例:
intタイプは戻り値として取得したコマンドラインパラメータを返してくれる。
       g = g01_getcmdlin_int_s(0);    // 0番目の引数を取得し、gに渡す
省略可能の場合・・・
       g = g01_getcmdlin_int_o(0,100);    // 0番目の引数を取得し、もしなかったら規定値として
                                             100を返す

この流れで行くとstrタイプも・・・・
       *g = g01_getcmdlin_str_s0(0);    // 0番目の文字型引数を取得し、gに渡す
省略可能の場合・・・
       *g = g01_getcmdlin_str_s0(0,"イカ自身");    // 0番目の文字型引数を取得し、gに渡すが、
                                                      もし指定がなかったら規定値として
                                                      「イカ自身」という文字を返す

しかし、実際には戻り値がないタイプだったのでこれは間違い。

こんなコードを書いてみる。

#include <guigui01.h>
#include <stdio.h>

unsigned char cmdusage[] = {
  0x86,  /* これは決まり文句なのでとりあえず変更しない */
  0x55,  /* 通常モード(引数名省略不可) */

  0x0c, 2, 'o','p','t', 0x3c, 9, 0x01, 'i', 'o', 'n', '-', 'f', 'i', 'l', 'e',

  0x40 /* 最後のこれも決まり文句なので変更しない */
};

void G01Main()
{
  g01_setcmdlin(cmdusage);          //コマンドライン定義

  char *buffer = g01_bss1a1;        //お便利バッファ2MBを宣言
  g01_getcmdlin_str_s0(0,100,buffer);    //引数受け取り

  g01_putstr0(buffer);
  return;
}
  • これは問題ない。引数無指定ならUsageが表示される。
  • opt:uniba-G! なんて引数を与えると、ちゃんと画面に表示されて終了する。
  • ここで、引数のタイプを省略可能にしてみる。 0x1c, 2, 'o','p','t', 0x3c, 9, 0x01, 'i', 'o', 'n', '-', 'f', 'i', 'l', 'e',
  • このままコンパイルしても、エラーになってしまう。(引数指定と受け取り指定がズレるからかなたぶん)
  • なので、受け取り側も省略可能タイプと指定。 g01_getcmdlin_str_o0(0,100,buffer); //引数受け取り
  • これでいままでと同じように動作する。(しいて違いを言えば、無指定の時、省略可能なのでUsage表示をしない)

うーん・・・やはり、intが特殊だったって法則でいいのかな。本来は規定値なんて概念はない。自分で戻り値を検証するコードを書け。・・・で。intだけは便利にしといたよ!・・・みたいな? www

Page Top

g01_getcmdlin_fopen系 anchor.png

ファイルパスタイプのデータを受け取る。(ファイルパスを受け取って開かないわけはない!ということで、fopenと一体型になっているのだろう。きっと)

Page Top

g01_getcmdlin_fopen_s系 anchor.png

省略不可に設定されたファイルパスを取得し、オープンする???

  • g01_getcmdlin_fopen_s(i)

・・・この流れで行けばoは省略可能の場合だと思うのだが、じゃ、規定値はどうするのこれ???

iは?? スロットの指摘? 引数番号??

困ったなぁ 載ってないぞ・・・・

  • g01_getcmdlin_fopen_o(i)
  • g01_getcmdlin_fopen_m(i, j)
  • g01_getcmdlin_fopen_s_0_4(i)
    こいつの正体はわかってるけど省略形なので後回し・・・・・・
  • g01_getcmdlin_fopen_s_3_5(i)
  • g01_getcmdlin_fopen_m_0_4(int i, int j)
  • g01_getcmdlin_fopen_o_0_4(int i)
  • g01_getcmdlin_fopen_o_3_5(int i)

うっちゃんの予測を検証すべく、実験をしてみた

こんなコードを書く。

#include <guigui01.h>
#include <stdio.h>

unsigned char cmdusage[] = {
  0x86,  /* これは決まり文句なのでとりあえず変更しない */
  0x55,  /* 通常モード(引数名省略不可) */

  0x0c, 2, 'o','p','t', 0x0c, 9, 0x01, 'i', 'o', 'n', '-', 'f', 'i', 'l', 'e',

  0x40 /* 最後のこれも決まり文句なので変更しない */
};

void G01Main()
{
  g01_setcmdlin(cmdusage);          //コマンドライン定義

  char *buffer = g01_bss1a1;        //お便利バッファ2MBを宣言
  g01_getcmdlin_fopen_s_0_4(0);    //引数受け取り&ファイルオープン

  jg01_fread0_4(2 * 1024 * 1024, buffer); /* 最大2MB, 終端に0がつく */
  g01_putstr0(buffer);
  return;
}
  • まずこれは正常に動作した。引数は省略不可なので指定しないとUsageが表示される。(一種のエラーかな・・)
  • 次に、引数側を省略可能にした。つまりこう。 0x1c, 2, 'o','p','t', 0x0c, 9, 0x01, 'i', 'o', 'n', '-', 'f', 'i', 'l', 'e',
  • 引数を指定しないと跳んでしまう・・・・
  • 引数を前回と同じもので指定しても、エラーが返される。
    debug: cmdlin_fopen: 4 56 test.txt
    c_api: junk_fopen: error

省略可能引数なので、それに合わせるべく、fopen側をイジる。つまり、g01_getcmdlin_fopen_o_0_4(0);

  • 跳ばない。でもUsageを表示せずに終了(・・・これはええと。正しい動作なのかな???たぶん)
  • 引数(ファイル名)を指定すると、最初の引数省略不可の場合と同じ動作をしてくれる(つまり、正常動作?)
Page Top

m系列・・・? anchor.png

if (g01_getcmdlin_fopen_m_0_4(0, j) == 0)

cpyのソース内でこんなことしてる・・・ぞ? m系列はあえて後回しにしてたんだけど、これは戻り値をもっている??

Page Top

g01_getcmdlin_argc anchor.png

指定した引数番号の引数が指定されているかどうかを判定する。

int g;                            ←引数の状態を受け取る変数
int i; i = 0;                     ←何番の引数について調べるか?
g = g01_getcmdlin_argc(i);        ←引数番号0の引数が指定されているかどうかの答えがgに入る。
                                      指定されていれば1、なければ0が返される。
  • g01_getcmdlin_argc(int i)
Page Top

g01_getcmdlin_flag系 anchor.png

g01_getcmdlin_flag_o(0)

  • g01_getcmdlin_flag_s(int i)
  • g01_getcmdlin_flag_o(i)
  • g01_getcmdlin_flag_s(i)
  • g01_getcmdlin_flag_s(i)
Page Top

未分類 anchor.png

  • g01_getcmdlin_exit1()
  • g01_getcmdlin_put0_s(i)
  • g01_getcmdlin_put1_s(i)
  • g01_getcmdlin_put0_m_exit1(i, j)
  • g01_getcmdlin_put1_m_exit1(i, j)
  • g01_cmdlin3s(int l) {}
  • g01_cmdlin3m(int l, int i) {}
  • g01_cmdlin4s(int l) {}
  • g01_cmdlin4m(int l, int i) {}
  • g01_cmdlin5s(int l) {}
  • g01_cmdlin5m(int l, int i) {}
  • g01_cmdlin6s1(int l, int n, void *p) {}
  • g01_cmdlin6m1(int l, int i, int n, void *p) {}
  • jg01_getcmdline0
  • jg01_getcmdlin1
  • jg01_getcmdline1
  • jg01_getcmdlin0
  • jg01_getcmdlin0(int n, void *p)
  • jg01_getcmdlin1(n, p)
Page Top

オイラ的な備考 anchor.png

このUsage表示(コマンドライン定義)では、省略形を使う場合はかならずソースにベタ書きをのこしておくといいと思う。


一般用コメント一覧

  • g01_getcmdlin_str_s0の規定値っていうのは、もしかしたらもともとs[]にセットした値かもしれませんね。戻り値があるg01_getcmdlin_int系の場合は、規定値が必要だけれど、パラメータとして結果の格納場所を指定するg01_getcmdlin_str_s0の場合は、API関数内部で規定値を与えなくても、ユーザーが勝手に規定値を設定できますからね。  --  uchan   2010/2/7 8:48
一般用コメント欄は使用できません

Last-modified: 2010-02-08 (月) 00:00:00 (JST) (319d) by lina