tkomatsu/minishell

基本的な構造

Closed this issue · 11 comments

Shell Operation

The following is a brief description of the shell’s operation when it reads and executes a command. Basically, the shell does the following:

  1. Reads its input from a file (see Shell Scripts), from a string supplied as an argument to the -c invocation option (see Invoking Bash), or from the user’s terminal.
  2. Breaks the input into words and operators, obeying the quoting rules described in Quoting. These tokens are separated by metacharacters. Alias expansion is performed by this step (see Aliases).
  3. Parses the tokens into simple and compound commands (see Shell Commands).
  4. Performs the various shell expansions (see Shell Expansions), breaking the expanded tokens into lists of filenames (see Filename Expansion) and commands and arguments.
  5. Performs any necessary redirections (see Redirections) and removes the redirection operators and their operands from the argument list.
  6. Executes the command (see Executing Commands).
  7. Optionally waits for the command to complete and collects its exit status (see Exit Status).

Bash Reference Manual

Bashの処理の流れはこんな感じらしい。
2からをパースとして考えていたけど、
1-2: Read
3-5: Parse
6-7: Execute
と考えた方がいい気がした。
そうじゃないとパースの部分が重すぎる感じがする 🤔

@kefujiwa
2で入力の文字列をメタ文字(‘|’, ‘&’, ‘;’, ‘(’, ‘)’, ‘<’, or ‘>’)を分割するところまでをReadの機能としてやってしまいたいです。

@tkomatsu
ここ早めに実装しないとボトルネックになりそうだね汗
ここ今日、明日中に対応します。
この場合、split_exec関数のsplit処理をread側に移行することになるかな?
処理のベースになるところだから、どこかの時間帯で対面レビューお願いしたい!

#29 で一部対応してくれるのか!確認します。

void minish_loop(void)
{
char *line;
int status;
status = 1;
while (status)
{
ft_putstr_fd("> ", 1);
read_arg(&line);
status = parse_exec(line);
ft_free(line);
}
}

この部分の lineを文字列配列にするか、 t_listで実装しないといけなくなりそう

どこまで増えるかわからないことを考えると、 t_listで実装が良い気はする

  1. 標準入力を読みこむ
  2. メタ文字で分割し、トークンに分ける
  3. トークンを複合コマンドにする(今回の課題では考えなくてもいい?)
  4. 変数($始まりなど)とファイル名のワイルドカードを反映し、コマンドと引数のリストにする
  5. リダイレクトの実装
  6. コマンド(ビルトイン・バイナリ)の実行
  7. ステータスの管理

t_listcontentは文字列でいいのかは考えた方がいいかも。
リダイレクトとかはフラグをつけて管理するなら

typedef struct s_token
{
char *str;
int flag;
}  t_token;

みたいな感じにする必要がありそう

@kefujiwa
Readが終わった段階は以下のように定義するといいのかな。

typedef struct s_token
{
char *word;
int metachar;
}  t_token;

t_list tokens;
tokens->content = (t_token*);

連結リストで、トークンを形成。メタ文字のフラグはビットマスクで立てる。

#define    SPACE    (1<<1)  // ' '
#define    TAB    (1<<2)  // '\t'
#define    NEWLINE    (1<<3)   // '\n'
#define    PIPE    (1<<4)  // '|'
#define    AMPERSAND    (1<<5)  // '&'
#define    SEMICOLON    (1<<6)  // ';'
#define    P_BIGIN    (1<<7)  // '('
#define    P_END    (1<<8)  // ')'
#define    GREATER    (1<<9)  // '>'
#define    LESS    (1<<10)  // '<'

https://github.com/tkomatsu/minishell/tree/dev_read

まだ途中(セグフォで動いてない)ですが、イメージの共有はできると思います 😃
branch切ってreadの部分を書いてみてます。

基本的な構造は全て実装完了した認識のため、本件クローズします。