Unix-Linux編程實踐教程——shell(3)

相較前一個版本,主要是把main.cpp中的對命令直接執行換成了對命令進行處理,加了邏輯的判斷。

頭文件controlflow.h

//
// Created by Jimmy on 3/25/20.
//

#ifndef WHO_CONTROLFLOW_H
#define WHO_CONTROLFLOW_H

#include <stdio.h>
#include "smsh.h"

enum states{
    NEUTRAL,
    WANT_THEN,
    THEN_BLOCK
};

enum results{
    SUCCESS,
    FAIL
};

static int if_state = NEUTRAL;
static int if_result = SUCCESS;
static int last_stat = 0;

int is_control_command(char *);
int do_control_command(char **);
int ok_to_execute();
int syn_err(char *);
int process(char **);

#endif //WHO_CONTROLFLOW_H

cpp文件controlflow.cpp

//
// Created by Jimmy on 3/25/20.
//

#include "include/controlflow.h"


int is_control_command(char * s)
{
    return (strcmp(s, "if") == 0 || strcmp(s, "then") == 0 || strcmp(s, "fi") == 0);
}

int do_control_command(char ** args)
{
    char * cmd = args[0];
    int rv = -1;

    if(strcmp(cmd, "if") == 0){
        if(if_state != NEUTRAL)
            rv = syn_err("if unexpected");
        else{
            last_stat = process(args + 1);//這裏是對if後的命令的再處理
            if_result = (last_stat == 0?SUCCESS:FAIL);
            if_state = WANT_THEN;
            rv = 0;
        }
    } else if(strcmp(cmd, "fi") == 0){
        if(if_state != THEN_BLOCK)
            rv = syn_err("fi unexpected");
        else{
            if_state = NEUTRAL;
            rv = 0;
        }
    } else if (strcmp(cmd, "then") == 0){
        if(if_state != WANT_THEN)
            rv = syn_err("then unexpected");
        else{
            if_state = THEN_BLOCK;
            rv = 0;
        }
    } else
        fatal("fatal err:", cmd, 2);
    return rv;
}

int syn_err(char * msg)
{
    if_state = NEUTRAL;
    fprintf(stderr, "syntax error: %s\n", msg);
    return -1;
}

int ok_to_execute()
{
    int rv = 1;

    if(if_state == WANT_THEN){
        syn_err("then expected");
        rv = 0;
    }
    else if(if_state == THEN_BLOCK && if_result == SUCCESS)
        rv = 1;
    else if(if_state == THEN_BLOCK && if_result == FAIL)
        rv = 0;
    return rv;
}

int process(char ** args)
{
    int rv = 0;

    if(args[0] == NULL)
        rv = 0;
    else if(is_control_command(args[0]))
        rv = do_control_command(args);
    else if(ok_to_execute())
        rv = execute(args);
    return rv;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章