相较前一个版本,主要是把
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;
}