パソコンでプログラミングしよう ウィンドウズC++プログラミング環境の構築
1.6.3.6(15)
ソースコード(Code::Blocksの環境変数カスタマイズ)

Code::BlocksのPATH改変における環境変数カスタマイズをソースコードから解析する。

ダウンロードリンク

ソースコード(抜粋)

環境変数カスタマイズ

環境変数カスタマイズはnsEnvVars::EnvvarApply(plugins\contrib\envvars\envvars_common.cpp:401)が行う。

bool nsEnvVars::EnvvarApply(const wxString& key, const wxString& value)
{
...
wxString value_set;
bool is_set = wxGetEnv(the_key, &value_set);
wxString the_value = value;
if (is_set)
{
std::map<wxString,wxString>::iterator it = nsEnvVars::EnvVarsStack.find(the_key);
if (it==nsEnvVars::EnvVarsStack.end()) // envvar not already on the stack
nsEnvVars::EnvVarsStack[the_key] = value_set; // remember the old value
// Avoid endless recursion if the value set contains e.g. $PATH, too
if (nsEnvVars::EnvvarIsRecursive(the_key,the_value))
{
...
// Restore original value in case of recursion before
if (it!=nsEnvVars::EnvVarsStack.end())
value_set = nsEnvVars::EnvVarsStack[the_key];
// Resolve recursion now (if any)
wxString recursion;
if (platform::windows) recursion = _T("%")+the_key+_("%");
else recursion = _T("$")+the_key;
the_value.Replace(recursion.wx_str(), value_set.wx_str());
}
}
// Replace all macros the user might have setup for the value
Manager::Get()->GetMacrosManager()->ReplaceMacros(the_value);
if (!wxSetEnv(the_key, the_value)) // set the envvar as computed
{
return false;
}
return true;
}// EnvvarApply

EnvVarsStackは環境変数名から値を連想するマップであり、既に定義されている環境変数を最初にカスタマイズする前の値を記憶する。nsEnvVars::EnvvarIsRecursive(plugins\contrib\envvars\envvars_common.cpp:353)でカスタマイズをチェックし、%VARIABLE%書式の再帰参照を記憶値に置き換える。その後MacrosManager::ReplaceMacros(sdk\macrosmanager.cpp:435)が参照する全変数を置き換えて、環境変数を変更する。

環境変数リセット

環境変数リセットはnsEnvVars::EnvvarDiscard(plugins\contrib\envvars\envvars_common.cpp:371)が行う。

bool nsEnvVars::EnvvarDiscard(const wxString &key)
{
...
std::map<wxString,wxString>::iterator it = nsEnvVars::EnvVarsStack.find(the_key);
if (it!=nsEnvVars::EnvVarsStack.end()) // found an old envvar on the stack
return nsEnvVars::EnvvarApply(the_key, it->second); // restore old value
if (!wxUnsetEnv(the_key))
{
...
return false;
}
return true;
}// EnvvarDiscard

リセットする環境変数の記憶値がEnvVarsStackに保存されていれば記憶値に戻し、さもなくば環境変数自体を削除する。記憶値に戻す場合もそのEnvVarsStack要素は削除しない。