// co_112_585.c
// ##############################################################
// ##
// ##  このプログラムはとっても危険かも知れません!!
// ##
// ##  実行中、PCにかなり負荷がかかった後
// ##  勝手に電源が落ちるかも知れません(熱暴走？)
// ##  実行される方は自己責任で。
// ##
// ##############################################################

#include <stdio.h>
#include <stdlib.h>

int check(void);
void make_code(int n);

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

    // 初期値 = 1 で開始し、2倍してコンパイルを試していく
    for (min_if = 1; min_if < 0x40000000; min_if *= 2) {
        fprintf(stderr, "testing %d", min_if);
        make_code(min_if);
        if (check()) {          //error
            break;
        }
        fprintf(stderr, "... コンパイル成功\n");
    }
    if (min_if >= 0x40000000) {
        fprintf(stderr, "%dまで試したがコンパイル出来た\n", 0x20000000);
        fprintf(stderr, "(これ以上は当プログラムでは試せない)\n");
        return 0;
    }
    // 挟みうちでコンパイルを試していく
    max_if = min_if;
    min_if /= 2;
    while (1) {
        n = (max_if + min_if) / 2;
        fprintf(stderr, "testing %d", n);
        make_code(n);
        if (check()) {          //error
            fprintf(stderr, "... コンパイル失敗\n");
            max_if = n;
        } else {
            fprintf(stderr, "... コンパイル成功\n");
            min_if = n;
        }
        if (max_if - min_if <= 1) {
            break;
        }
    }

    // 結果
    printf("\n\n");
    printf("%d個までは大丈夫\n", min_if);
    printf("%d個でコンパイルエラー\n", max_if);

    return 0;
}

// if ～ else を n 個作成
void make_code(int n)
{
    FILE *fp;
    int i;

    fp = fopen("test.c", "w");
    fprintf(fp, "int main(int argc, char *argv[])\n");
    fprintf(fp, "{\n");
    fprintf(fp, "  switch(argc) {\n");
    fprintf(fp, "    case 1:return 1;\n");
    for (i = 2; i <= n; i++) {
        fprintf(fp, "    case %d:return %d;\n", i, i);
    }
    fprintf(fp, "    default:break;\n");
    fprintf(fp, "  }\n");
    fprintf(fp, "  return 0;\n");
    fprintf(fp, "}\n");
    fclose(fp);
}

// make_code(); で生成された test.c がコンパイル出来るかテスト
int check(void)
{
    int res;
    res = system("gcc -c -Wall test.c");
    if (res == 0) {
        remove("test.o");
    }
    return res;
}

// End of co_112_585.c
