言語 RubyかC++か
シェルスクリプトは、もうイヤなんです。
ということで、言語を変えて全部書き直すわけですが、言語の選択がこの先に大きな影響をあたえるはず。
今の自分のスキル(CとPHPしかやったことないんですけど...)から考えて、C、C++、Ruby、Javaが考えられます。
まず、JavaはVMが巨大なので、ネットワークブート時のtftpでの転送中に、データが破損して起動に失敗する確率が高くなってしまう。tftpはUDPで信頼性が低い。組み込み向けのJava VMもあるものの、メモリやCPUに制限は無いので、これもどうか。そもそもx86の組み込み向けJava VMってあるんだろうか?ライセンスの問題も絡む。
Cは、難しい...。バイナリのサイズや実行速度は圧倒的なものの、プログラミングが難しい。それに、自分のスキルアップのためには、ここでオブジェクト指向言語を選択しておきたい気分。
で、残ったのはC++とRuby。試しにブートパラメータをパースするプログラム(クラス)を両方の言語で作ってみました。
C++
ちなみに、C++は(も)初心者です。
#include <iostream> #include <string> #include <map> #include <fstream> namespace VIVER { using namespace std; typedef map<string,string> Parameter_t; class Parameter { private: Parameter_t mParameters; public: // コンストラクタ Parameter() { } // デストラクタ ~Parameter() { mParameters.clear(); } void Parse(void) { string param; ifstream cmdline ("/proc/cmdline"); string::size_type poseq; pair<Parameter_t::iterator,bool> ins; while (cmdline >> param) { poseq = param.find_first_of('='); if (poseq != string::npos) { cout << "値付きパラメータ: " << param.substr(0,poseq) << " = " << param.substr(poseq + 1) << "\n"; // 値付きパラメータ ins = mParameters.insert( Parameter_t::value_type( param.substr(0,poseq), param.substr(poseq + 1) ) ); if (!ins.second) { // キーが重複 -> 上書き mParameters[param.substr(0,poseq)] = param.substr(poseq + 1); } } else { cout << "単発のパラメータ: " << param << "\n"; // 単発のパラメータ ins = mParameters.insert( Parameter_t::value_type( param, "1" ) ); if (!ins.second) { // キーが重複 -> 上書き mParameters[param] = "1"; } } } cmdline.close(); } string GetValue(string key) { Parameter_t::const_iterator n = mParameters.find(key); if (n == mParameters.end() ) { return ""; // 該当パラメータ無し } else { return n->second; } } }; // class Parameter } // namespace VIVER using namespace VIVER; int main(void) { Parameter param; param.Parse(); std::cout << param.GetValue("sata"); return 0; }
Ruby
Rubyも初心者。
#!/usr/bin/ruby module VIVER class Parameter def initialize @params = Hash.new end def parse begin cmdline = File.open("/proc/cmdline") cmdline.gets.split.each {|arg| if /([^=]*)=(.*)/ =~ arg @params[$1] = $2 else @params[arg] = true end } cmdline.close rescue => ex print ex.message + "\n" end end def get(key) # keyが存在しなかったら戻り値はnil return @params[key] end end # class Parameter end # module VIVER include VIVER parameter = Parameter.new parameter.parse p parameter.get("vga")