はじめに
mfiler4というファイラーがあります。
http://sourceforge.jp/projects/mfiler4/
mfiler4 1.1.1をUbuntu 12.04LTSの環境でコンパイルしようとしたときに、以下のようなコンパイルエラーに遭遇しました。
git HEADでも状況は同様でした。
-[3527]% LANG=C make
gcc -DSYSCONFDIR="\"/home/kenhys/etc/mfiler4/\"" -DDATAROOTDIR="\"/home/kenhys/share/doc/mfiler4/\"" -DSYSTEM_MIGEMODIR="\"/usr/share/cmigemo\"" -Isrc/ -I/home/kenhys/include -L/home/kenhys/lib -I . -I/usr/local/include -L/usr/local/lib -Werror -c -o src/filer.o src/filer.c
src/filer.c: In function 'make_file_stat':
src/filer.c:1441:9: error: format '%d' expects argument of type 'int', but argument 4 has type '__nlink_t' [-Werror=format]
src/filer.c:1441:9: error: format '%d' expects argument of type 'int', but argument 4 has type '__nlink_t' [-Werror=format]
src/filer.c: In function 'cmdline_view_filer':
src/filer.c:2530:13: error: format '%d' expects argument of type 'int', but argument 5 has type '__nlink_t' [-Werror=format]
src/filer.c:2530:13: error: format '%d' expects argument of type 'int', but argument 5 has type '__nlink_t' [-Werror=format]
src/filer.c:2549:12: error: format '%d' expects argument of type 'int', but argument 5 has type '__nlink_t' [-Werror=format]
src/filer.c:2549:12: error: format '%d' expects argument of type 'int', but argument 5 has type '__nlink_t' [-Werror=format]
cc1: all warnings being treated as errors
make: *** [src/filer.o] Error 1
問題点とパッチ
64bit環境と、それ以外では型修飾子に指定すべきものが違う、というのが肝です。
そこで以下のようにしてみました。longかそうでないかで分岐します。
diff --git a/src/common.h b/src/common.h
index b724127..1b65350 100644
--- a/src/common.h
+++ b/src/common.h
@@ -38,6 +38,12 @@
#define S_IXUGO (S_IXOTH | S_IXGRP | S_IXUSR)
+#if defined(__x86_64__)
+ #define FORMAT_HARDLINK "%3ld"
+#else
+ #define FORMAT_HARDLINK "%3d"
+#endif
+
diff --git a/src/filer.c b/src/filer.c
index 2d03879..d52eaa8 100644
--- a/src/filer.c
+++ b/src/filer.c
@@ -1436,7 +1436,7 @@ static void make_file_stat(sFile* file, char* buf, int buf_size)
char* env_nlink = getenv("VIEW_NLINK");
if(env_nlink && strcmp(env_nlink, "1") == 0) {
- snprintf(buf + strlen(buf), buf_size -strlen(buf), " %3d", file->mStat.st_nlink);
+ snprintf(buf + strlen(buf), buf_size -strlen(buf), " "FORMAT_HARDLINK, file->mStat.st_nlink);
}
char* env_owner = getenv("VIEW_OWNER");
@@ -2516,7 +2516,7 @@ void cmdline_view_filer()
while(year > 100) year-=100;
snprintf(buf2, 1024,
- "%s %3d %-8s %-7s%s %02d-%02d-%02d %02d:%02d %s"
+ "%s "FORMAT_HARDLINK" %-8s %-7s%s %02d-%02d-%02d %02d:%02d %s"
, permission, file->mLStat.st_nlink
, owner, group
@@ -2534,7 +2534,7 @@ void cmdline_view_filer()
}
else {
snprintf(buf, 1024,
- "%s %3d %s%s%s %02d-%02d-%02d %02d:%02d %s -> %s"
+ "%s "FORMAT_HARDLINK" %s%s%s %02d-%02d-%02d %02d:%02d %s -> %s"
, permission, file->mLStat.st_nlink
, owner, group
これともうひとつcursesがらみでもエラーになる部分がありました。
そちらはA_*がunsigned longとして定義されていることに由来するものです。
-[3508]% grep A_REVERSE /usr/include*.h
/usr/include/curses.h:#define WA_REVERSE A_REVERSE
/usr/include/curses.h:#define A_REVERSE NCURSES_BITS(1UL,10)
/usr/include/ncurses.h:#define WA_REVERSE A_REVERSE
/usr/include/ncurses.h:#define A_REVERSE NCURSES_BITS(1UL,10)
/usr/include/ncursesw/curses.h:#define WA_REVERSE A_REVERSE
/usr/include/ncursesw/curses.h:#define A_REVERSE NCURSES_BITS(1UL,10)
/usr/include/ncursesw/ncurses.h:#define WA_REVERSE A_REVERSE
/usr/include/ncursesw/ncurses.h:#define A_REVERSE NCURSES_BITS(1UL,10)
こちらについても、パッチは似たような感じになります。
diff --git a/src/main.c b/src/main.c
index 8ebe03c..e95ac19 100644
--- a/src/main.c
+++ b/src/main.c
@@ -541,11 +541,11 @@ static void set_mfenv()
setenv("nometa", buf, 1);
snprintf(buf,128, "%d", 1);
setenv("meta", buf, 1);
- snprintf(buf,128, "%d", A_REVERSE);
+ snprintf(buf,128, "%ld", A_REVERSE);
setenv("ma_reverse", buf, 1);
- snprintf(buf,128, "%d", A_BOLD);
+ snprintf(buf,128, "%ld", A_BOLD);
setenv("ma_bold", buf, 1);
- snprintf(buf,128, "%d", A_UNDERLINE);
+ snprintf(buf,128, "%ld", A_UNDERLINE);
setenv("ma_underline", buf, 1);
snprintf(buf,128, "%d", COLOR_PAIR(1));
setenv("ma_white", buf, 1);