標準入出力とpipeを実装中
入力されたアルファベット文字列を大文字化するプログラム upper は以下のような挙動を要求される。
1.コマンドライン引数で渡された文字列を大文字化する
%upper higepon => HIGEPON
2.キーボードで入力された文字列を大文字化する
%upper (キー入力で higepon + ENTER) => HIGEPON
3.他のプロセスからpipeで渡された場合
%print higepon | upper => HIGEPON
実は 2, 3はあまり違いは無い。
どちらも upper は標準入力を read して upper case すれば良いだけだ。
これを Mona で実現するためにシェルとAPIを用意してプリミティブな関数で書いてみたのが以下のコード。
#include <monapi.h>
#include <monalibc.h>
#include <string>
using namespace std;
void toUpper(char* text, int length);
string readLine();
int MonaMain(List<char*>* pekoe)
{
// upper argument text
if (pekoe->size() > 0)
{
char* text = pekoe->get(0);
toUpper(text, strlen(text));
monapi_stdout_write((byte*)text, strlen(text) + 1);
return 0;
}
// upper string which read from stdin
monapi_stdin_lock_for_read();
string result = readLine();
monapi_stdin_unlock_for_read();
char* text = new char[result.size()];
strcpy(text, result.c_str());
toUpper(text, result.size());
monapi_stdout_write((byte*)text, result.size());
delete[] text;
return 0;
}
string readLine()
{
string result("");
for (;;) {
byte buffer[256];
dword size = monapi_stdin_read(buffer, 256);
for (dword i = 0; i < size; i++)
{
result += buffer[i];
if (buffer[i] == '\n' || buffer[i] == '\0') return result;
}
}
return result;
}
void toUpper(char* text, int length)
{
for (int i = 0; i < length; i++)
{
text[i] = toupper(text[i]);
}
}プリミティブな関数たちを libc でwrapすればより一般的な方法で書けるところまで来たかな。
まだ課題は多いけど。