gnatelim 解決編
動いた…。
gnatelim-process_bind_file.adbのGet_Lineの下に以下を挿入します。
while Elab_Proc_NInd <= Elab_Proc_NLen loop case Elab_Proc_Name (Elab_Proc_NLen) is when Character'Val(13) | Character'Val(10) => Elab_Proc_NLen := Elab_Proc_NLen - 1; when others => exit; end case; end loop;
恐らくバイナリファイルを扱うためにbinmodeを使うのでしょう。その上で普通にテキストファイル処理を行ってしまっているため、改行コードまでGet_Lineが取り込んでいるものと思われます。
この時点でCバインダー(gnatbind -C testで生成)は動きます。
Adaバインダーを動かすにはさらに、バージョン違いかなにかで"-- BEGIN ELABORATION ORDER"とかの"--"の後のスペースの数が違いますので地道に修正。
Result := Elab_Proc_Name (Elab_Proc_NInd .. Elab_Proc_NLen) = "-- END ELABORATION ORDER";
↓
Result := Elab_Proc_Name (Elab_Proc_NInd .. Elab_Proc_NLen) = "-- END ELABORATION ORDER" or else Elab_Proc_Name (Elab_Proc_NInd .. Elab_Proc_NLen) = "-- END ELABORATION ORDER";
exit when Elab_Proc_Name (Elab_Proc_NInd .. Elab_Proc_NLen) = "-- BEGIN ELABORATION ORDER";
↓
exit when Elab_Proc_Name (Elab_Proc_NInd .. Elab_Proc_NLen) = "-- BEGIN ELABORATION ORDER" or else Elab_Proc_Name (Elab_Proc_NInd .. Elab_Proc_NLen) = "-- BEGIN ELABORATION ORDER";
同様にこんな定数決め打ちも…。
Elab_Proc_NInd := Elab_Proc_NInd + 3; -- Skip "-- "
↓
while Elab_Proc_Name(Elab_Proc_NInd) = '-' loop Elab_Proc_NInd := Elab_Proc_NInd + 1; end loop; while Elab_Proc_Name(Elab_Proc_NInd) = ' ' loop Elab_Proc_NInd := Elab_Proc_NInd + 1; end loop;
朝から疲れた。
gnatmake -f -c -gnatc -gnatt test gnatbind test gnatelim test > gnat.adc gnatmake -f test
test.adbに、決して他から呼ばれることがないルーチン(関数内関数でも可)を紛れ込ませておけば、サイズが変わっていることを確認できます。
ここまでしたのですからパッチ送りつけてやりたいなあ…。
ちなみに使い方はhttp://gcc.gnu.org/onlinedocs/gcc-3.4.3/gnat_ugn_unw/Summary-of-the-gnatelim-Usage-Cycle.html参照。
追記
gcc-4.0.1。あとAda2005の機能には残念ながら未対応。
function Get_Unit_From_C_Elab_Procedure return Compilation_Unit is begin -- while Elab_Proc_Name (Elab_Proc_NLen) /= ' ' loop while Elab_Proc_Name (Elab_Proc_NLen) /= '%' loop Elab_Proc_NLen := Elab_Proc_NLen - 1; end loop; -- Skip "(spec)" or "(body") -- if Elab_Proc_Name (Elab_Proc_NLen + 2) = 's' then if Elab_Proc_Name (Elab_Proc_NLen + 1) = 's' then Spec := True; else Spec := False; end if; Elab_Proc_NLen := Elab_Proc_NLen - 1; -- Skip ' ' between the unit name and "(spec|body)" Unit_Name_Len := Elab_Proc_NLen - Elab_Proc_NInd + 1; Unit_Name (1 .. Unit_Name_Len) := To_Lower (Elab_Proc_Name (Elab_Proc_NInd .. Elab_Proc_NLen)); -- here we have a unit name as Unit_Name (1 .. Unit_Name_Len); if Spec then return Library_Unit_Declaration (To_Wide_String (Unit_Name (1 .. Unit_Name_Len)), C); else return Compilation_Unit_Body (To_Wide_String (Unit_Name (1 .. Unit_Name_Len)), C); end if; end Get_Unit_From_C_Elab_Procedure;