メモ代わり。てきとーに。 いや、ですからてきとーですって。 2年前ぐらいにPythonあたりでメールくれた方、ごめんなさい。メール紛失してしまい無視した形になってしまいました。。。

2008年2月28日木曜日

[Apache][CodeReading] Apache2.2.8コードリーディング28日目

今日もApache2.2.8コードリーディング。

今日も、昨日と同じくDEBUGログまわり。
printf書式を実装している部分。

今日読んだところは、

  • FIX_PRECISIONローカルマクロ(apr_snprintf)/Apache2.2.8
  • conv_10_quad()/Apache2.2.8
  • conv_10()/Apache2.2.8
  • FALSEローカルマクロ(apr_snprintf)/Apache2.2.8
  • INT32_MINローカルマクロ(apr_snprintf)/Apache2.2.8
  • INT32_MAXローカルマクロ(apr_snprintf)/Apache2.2.8
  • APR_INT64_T_FMTマクロ/Apache2.2.8
らへん。
これらはapr_vformatterという関数からコールされている。

conv_10_quad()とconv_10()は、数値を数字列に変換する関数。
10進表記の文字列に変換する。
conv_10_quad()とconv_10()の違いは、64ビットか32ビットかの違い。
その名のとおり、quadは64ビットに対応する。

conv_10_quad()
この関数は"%lld"フォーマットに対応する。
で、以下、そのソース。

383 static char *conv_10_quad(apr_int64_t num, register int is_unsigned,
384 register int *is_negative, char *buf_end,
385 register apr_size_t *len)
386 {
387 register char *p = buf_end;
388 apr_uint64_t magnitude = num;
389
390 /*
391 * We see if we can use the faster non-quad version by checking the
392 * number against the largest long value it can be. If <=, we
393 * punt to the quicker version.
394 */
395 if ((magnitude <= APR_UINT32_MAX && is_unsigned)
396 || (num <= INT32_MAX && num >= INT32_MIN && !is_unsigned))
397 return(conv_10((apr_int32_t)num, is_unsigned, is_negative, buf_end, len));
398
399 if (is_unsigned) {
400 *is_negative = FALSE;
401 }
402 else {
403 *is_negative = (num < 0);
404
405 /*
406 * On a 2's complement machine, negating the most negative integer
407 * results in a number that cannot be represented as a signed integer.
408 * Here is what we do to obtain the number's magnitude:
409 * a. add 1 to the number
410 * b. negate it (becomes positive)
411 * c. convert it to unsigned
412 * d. add 1
413 */
414 if (*is_negative) {
415 apr_int64_t t = num + 1;
416 magnitude = ((apr_uint64_t) -t) + 1;
417 }
418 }
419
420 /*
421 * We use a do-while loop so that we write at least 1 digit
422 */
423 do {
424 apr_uint64_t new_magnitude = magnitude / 10;
425
426 *--p = (char) (magnitude - new_magnitude * 10 + '0');
427 magnitude = new_magnitude;
428 }
429 while (magnitude);
430
431 *len = buf_end - p;
432 return (p);
433 }
 

とりたてて面白いことをやっているわけではない。
あえて言うなら、
元の値から、10で割った後、10でかけて1桁目を0にした値を差し引いて
1桁目を取得していることぐらいか。
値そのものが、32ビットの範囲内であれば、conv_10()をコールする。

conv_10()
conv_10は大体conv_10_quad()と一緒。
やっていることもほぼ一緒。

APR_INT64_T_FMT
これは、"lld"と記述されている。それだけ。

他は特になし。



今日の分はここまで。

おしまい。
.

0 コメント: