GNUインデントが1レベルのインデントを縮小するのはなぜですか?

GNUインデントが1レベルのインデントを縮小するのはなぜですか?

次のようにCコードをフォーマットしようとしたときGNUインデント、複数レベルの入れ子になったインデントを処理できないようです。具体的にはインデント2段階が崩れるようです。

たとえば、これが私が始めるコードなら:

#include <stdio.h>

int main(int argc, char *argv[])
{
    int n;

    if (argc > 1) {
        printf("# of args: %d\n", argc);
    }

    for (n = 1; n <= 15; n++) {
        if (n % 3 == 0) {
            printf("fizz %d\n", n);
        } else if (n % 5 == 0) {
            printf("buzz %d\n", n);
        } else if (n % 3 == 0 && n % 5 == 0) {
            printf("fizzbuzz %d\n", n);
        } else {
            printf("%d\n", n);
        }
    }

    return 0;
}

を実行すると、indent -kr fizzbuzz.c次のような結果が得られます。

#include <stdio.h>

int main(int argc, char *argv[])
{
    int n;

    if (argc > 1) {
    printf("# of args: %d\n", argc);
    }

    for (n = 1; n <= 15; n++) {
    if (n % 3 == 0) {
        printf("fizz %d\n", n);
    } else if (n % 5 == 0) {
        printf("buzz %d\n", n);
    } else if (n % 3 == 0 && n % 5 == 0) {
        printf("fizzbuzz %d\n", n);
    } else {
        printf("%d\n", n);
    }
    }

    return 0;
}

indent fizzbuzz.cデフォルト()で実行すると、次の結果が表示されます。

#include <stdio.h>

int
main (int argc, char *argv[])
{
  int n;

  if (argc > 1)
    {
      printf ("# of args: %d\n", argc);
    }

  for (n = 1; n <= 15; n++)
    {
      if (n % 3 == 0)
    {
      printf ("fizz %d\n", n);
    }
      else if (n % 5 == 0)
    {
      printf ("buzz %d\n", n);
    }
      else if (n % 3 == 0 && n % 5 == 0)
    {
      printf ("fizzbuzz %d\n", n);
    }
      else
    {
      printf ("%d\n", n);
    }
    }

  return 0;
}

多くの人がそれが箱から出たのかどうか尋ねるようです。バグでなければ、コードを書式設定する非常に奇妙な方法のように見えるからです。なぜこのようなことをするのですか?

私はGNU Indentバージョン2.2.11を使用しています。

答え1

インデントには、スペースとタブ(8つのスペース)を混合して使用します。以下の最小限の例でこれを確認できます。

int main() {
    if (true) {
        while (false) {
            puts("");
        }
    }
}

再実行すると、indent -krhexdump -Cのような結果が表示されます。

$ indent -kr < mini.c |hexdump -C
00000000  69 6e 74 20 6d 61 69 6e  28 29 0a 7b 0a 20 20 20  |int main().{.   |
00000010  20 69 66 20 28 74 72 75  65 29 20 7b 0a 09 77 68  | if (true) {..wh|
00000020  69 6c 65 20 28 66 61 6c  73 65 29 20 7b 0a 09 20  |ile (false) {.. |
00000030  20 20 20 70 75 74 73 28  22 22 29 3b 0a 09 7d 0a  |   puts("");..}.|
00000040  20 20 20 20 7d 0a 7d 0a                           |    }.}.|
00000048

前に(水平タブ)バイトwhileがあり、前にタブと4つのスペース()があることがわかります。デフォルト値は次のようになります。09puts20

00000000  69 6e 74 0a 6d 61 69 6e  20 28 29 0a 7b 0a 20 20  |int.main ().{.  |
00000010  69 66 20 28 74 72 75 65  29 0a 20 20 20 20 7b 0a  |if (true).    {.|
00000020  20 20 20 20 20 20 77 68  69 6c 65 20 28 66 61 6c  |      while (fal|
00000030  73 65 29 0a 09 7b 0a 09  20 20 70 75 74 73 20 28  |se)..{..  puts (|
00000040  22 22 29 3b 0a 09 7d 0a  20 20 20 20 7d 0a 7d 0a  |"");..}.    }.}.|
00000050

ここには最も内側の支柱があり、タブがありますputs

-nut/オプション--no-tabsを使用すると、どこでもスペースを使用できます。

$ indent -kr -nut fizzbuzz.c

または、元のインデントを維持することが重要な場合は、4つではなく8つのワイドタブを使用するようにエディタおよび/または端末を設定できます。このexpandコマンドは、再インデントしたくない既存のファイルを変換するのに役立ちます。

関連情報