MochiOS@仮想ファイルシステムの作成part3

MochiOS@仮想ファイルシステムの作成part3

前提知識無しで作るなんちゃって仮想ファイルシステムpart3。

開発日記です。独り言です。

これまでのあらすじ

part 内容
0 仮想ファイルシステムを作りたい宣言をする。
1 ざっくり仮想ファイルシステムの機能を決める。
が、機能呼出し先の仮想ファイルシステムのタスクIDをどう取得するかという問題に気付く。
2 カーネルにタスク名登録機能を実装した。
これでタスク名からタスクIDを取得する事が出来る様になるハズ、なので試したいが試す方法が無い事に気付き、ログ出力タスクの開発を宣言する。

%dとか使いたいじゃん?

part3では、ログ出力機能も実装して、試してみて、わはーうまく動いてる。って書きたかったんだけど、欲張りな私は、printfみたいに「%d」とかで書式指定して変数の内容をログ出力したいと考えたわけだ。
というわけで、C標準ライブラリのvsnprintf()を実装したい。
  • 何故vsnprintf()かというと、log( "へんすうのあたい=%d", value );みたいにログ出力関数の引数を可変長にしたいから。

vsnprintf()の仕様

wikipediaさんによるとこんな規則なんですよ。
%[引数順][フラグ][最小フィールド幅][.精度][長さ修飾子]変換指定子
仕様がよくわからんので、どっかから拾ってきた仕様を、英語できないけどがんばって訳してみる。

引数順

ISO/IEC9899:1999には無さそうだし、見なかったことにするよ。

フラグ(flag)

Zero or more flags (in any order) that modify the meaning of the conversion specification.
変換指定の意味を修飾する0個以上のフラグ(順不同)
フラグ 英語説明
適当翻訳
- The result of the conversion is left-justified within the field. (It is right-justified if this flag is not specified.)
フィールドの中で左寄せされるんだぜ。(これ指定されなかったら右寄せよ)
+ The result of a signed conversion always begins with a plus or minus sign. (It begins with a sign only when a negative value is converted if this flag is not specified.)
符号付き変換は常に+か-符号から始まるぜ。(これ指定されなかったら負の数の時だけ符号から始めちゃう。)
space If the first character of a signed conversion is not a sign, or if a signed conversion results in no characters, a space is prefixed to the result. If the space and + flags both appear, the space flag is ignored.
符号付き変換で最初の文字が符号じゃないか、符号付き変換が文字にならないんなら、空白が前につくぜ。空白と+フラグが両方あったら空白フラグは無視されちゃうんだな。
# The result is converted to an ‘‘alternative form’’. For o conversion, it increases the precision, if and only if necessary, to force the first digit of the result to be a zero (if the value and precision are both 0, a single 0 is printed). For x (or X) conversion, a nonzero result has 0x (or 0X) prefixed to it. For a, A, e, E, f, F, g, and G conversions, the result of converting a floating-point number always contains a decimal-point character, even if no digits follow it. (Normally, a decimal-point character appears in the result of these conversions only if a digit follows it.) For g and G conversions, trailing zeros are not removed from the result. For other conversions, the behavior is undefined.
"alternative form(選択方式、代替形態)"に変換されっぜ。o変換に対しては、必要な時に限って、最初の桁を0に強制するんで精度を拡張する(値と精度が両方0なら一つの0が出力される)。x(かX)変換に対しては、非0は0x(か0X)が前に付く。
(続きは、気が向いたら。。)
0 For d, i, o, u, x, X, a, A, e, E, f, F, g, and G conversions, leading zeros (following any indication of sign or base) are used to pad to the field width rather than performing space padding, except when converting an infinity or NaN. If the 0 and - flags both appear, the 0 flag is ignored. For d, i, o, u, x, and X conversions, if a precision is specified, the 0 flag is ignored. For other conversions, the behavior is undefined.
d,i,o,u,x,X,a,A,e,E,f,F,g,G変換に対して、無限大や非数に変換される時を除いて、最初に空白埋めが行われるんでなく(符号か基数表示の後に続いて)0がフィールド幅を埋める為に使われるぜ。0と-フラグ両方が使われると0フラグは無視されちゃうよ。d,i,o,u,x,X変換に対しては、精度が指定されちゃってると0フラグは無視されちゃうよ。他の変換では、どうなるか決めてないよ。

最小フィールド幅(minimum field width)

An optional minimum field width. If the converted value has fewer characters than the field width, it is padded with spaces (by default) on the left (or right, if the left adjustment flag, described later, has been given) to the field width. The field width takes the form of an asterisk * (described later) or a decimal integer.
任意のフィールド幅。変換値がフィールド幅より少ない文字数なら、フィールド幅まで(デフォルトで)空白を左に埋めるぜ(後で記述される(この記事では前だけど) 左寄せフラグがある場合は右に埋める)。フィールド幅はアスタリスク*(後で記述)の形式か10進数整数をとっちゃうよ。

.精度(precision)

An optional precision that gives the minimum number of digits to appear for the d, i, o, u, x, and X conversions, the number of digits to appear after the decimal-point character for a, A, e, E, f, and F conversions, the maximum number of significant digits for the g and G conversions, or the maximum number of bytes to be written for s conversions. The precision takes the form of a period (.) followed either by an asterisk * (described later) or by an optional decimal integer; if only the period is specified, the precision is taken as zero. If a precision appears with any other conversion specifier, the behavior is undefined.
d, i, o, u, x, X変換に対しては最小桁数、a, A, e, E, f, F変換に対しては小数点後の桁数、g, G変換に対しては最大有効桁数、s変換に対しては書かれるべき最大バイト数を表す任意の精度。精度はピリオド.とそれに続いてアスタリスク*(後で記述)か任意の10進数整数の形式をとるぜ。ピリオドだけ指定される場合は0として扱うんだぜ。精度がその他の変換指定子で表れる場合の動作は未定義だぜ。
  • 浮動小数点の桁数だけだと思ってた…

長さ修飾子(length modifier)

An optional length modifier that specifies the size of the argument.
引数のサイズを指定する任意の長さ修飾子。
長さ修飾子 英語説明
適当翻訳
hh Specifies that a following d, i, o, u, x, or X conversion specifier applies to a signed char or unsigned char argument (the argument will have been promoted according to the integer promotions, but its value shall be converted to signed char or unsigned char before printing); or that a following n conversion specifier applies to a pointer to a signed char argument.
後に続くd,i,o,u,x,X変換指定子がsigned charかunsigned char引数に適用されることを指定するぜ(引数は整数拡張に従って拡張されるよん。だけどその値は出力する前にsigned charかunsigned charに変換されるべきだよ。(詳しい人この意味教えて。。。))。または、後に続くn変換指定子がsigned char引数へのポインタに適用されることを指定するぜ。
h Specifies that a following d, i, o, u, x, or X conversion specifier applies to a short int or unsigned short int argument (the argument will have been promoted according to the integer promotions, but its value shall be converted to short int or unsigned short int before printing); or that a following n conversion specifier applies to a pointer to a short int argument.
後に続くd,i,o,u,x,X変換指定子がshort intかunsigned short int引数に適用されることを指定するぜ(引数は整数拡張に従って拡張されるよん。だけどその値は出力する前にshort intかunsigned short intに変換されるべきだよ。)または、後に続くn変換指定子がshort int引数へのポインタに適用されることを指定するぜ。
l Specifies that a following d, i, o, u, x, or X conversion specifier applies to a long int or unsigned long int argument; that a following n conversion specifier applies to a pointer to a long int argument; that a following c conversion specifier applies to a wint_t argument; that a following s conversion specifier applies to a pointer to a wchar_t argument; or has no effect on a following a, A, e, E, f, F, g, or G conversion specifier.
後に続くd,i,o,u,x,X変換指定子がlong intかunsigned long int引数に適用されることを指定するぜ。後に続くn変換指定子がlong int引数へのポインタに適用されることを指定するぜ。後に続くc変換指定子がwint_t引数に適用されることを指定するぜ。後に続くs変換指定子がwchar_t引数へのポインタに適用されることを指定するぜ。後に続くa,A,e,E,f,F,g,G変換指定子では何の効果もないよ。
ll 気が向いたらね。
j 気が向いたらね。。
z Specifies that a following d, i, o, u, x, or X conversion specifier applies to a size_t or the corresponding signed integer type argument; or that a following n conversion specifier applies to a pointer to a signed integer type corresponding to size_t argument.
後に続くd,i,o,u,x,X変換指定子がsize_tか同様のsigned integer型引数に適用されることを指定するぜ。または後に続くn変換指定子がsize_t引数に相当するsigned integer型へのポインタに適用されることを指定するぜ。
t Specifies that a following d, i, o, u, x, or X conversion specifier applies to a ptrdiff_t or the corresponding unsigned integer type argument; or that a following n conversion specifier applies to a pointer to a ptrdiff_t argument.
後に続くd,i,o,u,x,X変換指定子がptrdiff_tか同様のunsigned integer type引数に適用されることを指定するぜ。または後に続くn変換指定子がptrdiff_t引数へのポインタに適用されることを指定するぜ。
L 気が向いたらね。。。

変換指定子(conversion specifier)

A conversion specifier character that specifies the type of conversion to be applied.
適応される変換タイプを指定する変換指定子文字。
変換指定子 英語内容
適当翻訳
d
i
The int argument is converted to signed decimal in the style [−]dddd. The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it is expanded with leading zeros. The default precision is 1. The result of converting a zero value with a precision of zero is no characters.
int引数が[-]ddddの形で符号付き10進数に変換されるぜ。精度は最小桁数を指定するぜ。変換される値が精度より少ない桁数なら、0で拡張される。デフォルトの精度は1だぜ。精度0で値0を変換したら文字は無くなっちゃうぜ。
o
u
x
X
The unsigned int argument is converted to unsigned octal (o), unsigned decimal (u), or unsigned hexadecimal notation (x or X) in the style dddd; the letters abcdef are used for x conversion and the letters ABCDEF for X conversion. The precision specifies the minimum number of digits to appear; if the value being converted can be represented in fewer digits, it is expanded with leading zeros. The default precision is 1. The result of converting a zero value with a precision of zero is no characters.
unsigned int引数が符号無し8進数表記に(o)、符号無し10進数表記に(u)、または符号無し16進数表記に(xかX)、dddd形式で変換されるぜ。文字abcdefがx変換指定子では使われて、文字ABCDEFがX変換指定子では使われるぞ。精度は最小桁数を指定するよ。変換される値がより少ない桁数で表されるならば、先頭0で拡張されるぜ。デフォルトの精度は1や。精度0で値0を変換したら文字は無いぜよ。
f
F
気が向いたらね。
e
E
気が向いたらね。。
g
G
気が向いたらね。。。
a
A
気が向いたらね。。。。
c If no l length modifier is present, the int argument is converted to an unsigned char, and the resulting character is written. If an l length modifier is present, the wint_t argument is converted as if by an ls conversion specification with no precision and an argument that points to the initial element of a two-element array of wchar_t, the first element containing the wint_t argument to the lc conversion specification and the second a null wide character.
長さ修飾子lが指定されないなら、int引数がunsigned charに変換されて、その結果の文字が書かれるよ。長さ修飾子lが指定されるなら、精度無しでwchar_tの2要素配列(最初の要素はlc変換指定へのwint_t引数を含み、二つ目の要素はnullワイド文字を含む)の先頭を指し示す引数を持つls変換指定のように、wint_t引数が変換されるぜ。
s If no l length modifier is present, the argument shall be a pointer to the initial element of an array of character type. Characters from the array are written up to (but not including) the terminating null character. If the precision is specified, no more than that many bytes are written. If the precision is not specified or is greater than the size of the array, the array shall contain a null character. If an l length modifier is present, the argument shall be a pointer to the initial element of an array of wchar_t type. Wide characters from the array are converted to multibyte characters (each as if by a call to the wcrtomb function, with the conversion state described by an mbstate_t object initialized to zero before the first wide character is converted) up to and including a terminating null wide character. The resulting multibyte characters are written up to (but not including) the terminating null character(byte). If no precision is specified, the array shall contain a null wide character. If a precision is specified, no more than that many bytes are written (including shift sequences, if any), and the array shall contain a null wide character if, to equal the multibyte character sequence length given by the precision, the function would need to access a wide character one past the end of the array. In no case is a partial multibyte character written.
長さ修飾子lが指定されないなら、引数はchar型配列の先頭ポインタでなければならない。配列から文字達は終端null文字まで書かれる(けどnull文字は書かれないよ)。精度が指定されるなら、精度以上のバイトは書かれない。精度が指定されないか精度が配列サイズより大きければ、配列はnull文字を含むべきだ。長さ修飾子が指定されるなら、引数は、wchar_t型配列の先頭ポインタであるべきだ。配列からワイド文字は終端nullワイド文字を含むまでマルチバイト文字に(それぞれ、wcrtomb関数呼び出しによる様に、mbstate_tオブジェクト(最初のワイド文字が変換される前に0に初期化される)によって記述される変換状態で)変換される。(以下略。。。疲れた。。。)
p The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.
引数はvoidポインタであるべきやね。ポインタ値は実装で定義される方法で一連の表示文字に変換されるわ。
n 気が向いたらね。。。。。
% A % character is written. No argument is converted. The complete conversion specification shall be %%.
%文字が書かれる。変換される引数はないっす。完ペキな変換指定は%%であるべきっす。

note
a field width, or precision, or both, may be indicated by an asterisk. In this case, an int argument supplies the field width or precision. The arguments specifying field width, or precision, or both, shall appear (in that order) before the argument (if any) to be converted. A negative field width argument is taken as a - flag followed by a positive field width. A negative precision argument is taken as if the precision were omitted.
最小フィールド幅と精度はアスタリスクによって示されることができるっす。この場合、int型引数がフィールド幅か精度になるっす。必ずフィールドアバか精度かその両方を指定する引数は変換されるための引数(もしあれば)より前に(順番に)表れるっす。負のフィールド幅引数は-フラグ(この後に正のフィールド幅が続く)として扱われるっす。負の精度引数は精度が省略された様に扱われるっす。っすっすっす。

実装方針を決める。

一言で言うと、「だるっ!」
こんな方針で実装しようそうしよう。
  • 引数順はちょっと見なかったことにしよう。
  • フラグはちょっとがんばろうかな。
  • 最小フィールド幅もがんばろう。
  • 精度はうーん浮動小数点演算以外も使えるの知らなかった。。。がんばろ。
  • 長さ修飾子は4バイトまでなら対応する。あとは知らない。32bitOSだし(そういうことじゃない
  • 変換指定子も浮動小数点数とよくわからないのは見なかったことにするか。
英語読むだけで疲れたわ!誤訳ばっかだわたぶん!恥ずかしい!ごめん!

コメント

このブログの人気の投稿

プライバシーポリシー

git@よく使うコマンド早見表