1 Star 0 Fork 0

冰雪不语 / iceshell

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
parse.c 4.84 KB
一键复制 编辑 原始数据 按行查看 历史
冰雪不语 提交于 2015-05-09 16:40 . 增加cd和命令错误功能
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <fcntl.h>
#include "parse.h"
#include "init.h"
#include "extern.h"
#include "execute.h"
#include "builtin.h"
/*
* linux内核2.6.24之后取消了在limits.h头文件中定义的OPEN_MAX
* 要使用的话需自行定义,可以考虑使用sysconf(_SC_OPEN_MAX)
*/
//#define OPEN_MAX 1024
void get_name(char *name);
void printf_command();
/*
* shell主循环
*/
void shell_loop(void)
{
while (1) {
/* 初始化环境 */
init();
/* 获取命令 */
if (read_command() == -1)
break;
/* 解析命令 */
parse_command();
//printf_command();
/* 执行命令 */
execute_command();
}
printf("\nexit\n");
}
/*
* 读取命令
* 成功返回0,失败或者读取到文件结束符(EOF)返回-1
*/
int read_command(void)
{
/* 按行读取命令,cmdline中包含'\n'字符 */
if (fgets(cmdline, MAXLINE, stdin) == NULL)
return -1;
return 0;
}
/*
* 解析命令
* 成功返回解析到的命令个数,失败返回-1
*/
int parse_command(void)
{
/* 如果第一条命令为回车,直接返回 */
if(check("\n"))
return 0;
/* 判断是否内部命令,是则执行 */
if(builtin())
return 0;
/* 1.解析第一条命令 */
get_command(0);
/* 2.判定是否有输入重定向 */
if(check("<"))
get_name(infile);
/* 3.判定是否有管道 */
int i;
for(i=1; i<PIPELINE; i++) {
if(check("|"))
get_command(i);
else
break;
}
/* 4.判定是否有输出重定向 */
if(check(">")) {
if(check(">")) {
append = 1;
}
get_name(outfile);
}
/* 5.判定是否后台作业 */
if(check("&"))
backgnd = 1;
/* 6.判定是否命令结束'\n' */
if(check("\n")) {
cmd_count = i;
return cmd_count;
} else {
fprintf(stderr, "Command line syntax error!\n");
return -1;
}
return 0;
}
/*
* 执行命令
* 成功返回0,失败返回-1
*/
int execute_command(void)
{
execute_disk_command();
return 0;
}
/*
* 解析命令至cmd[i]
* 提取cmdline中的命令参数至avline数组
* 将COMMAND结构中的args[]中的每个指针指向这些参数
*/
void get_command(int i)
{
int j = 0;
int inword;
while(*lineptr != '\0') {
/* 去除空格和制表符 */
while(*lineptr == ' ' || *lineptr == '\t')
lineptr++;
/* 将第i个命令和第j个参数指向avptr */
cmd[i].args[j] = avptr;
/*提取参数*/
while(*lineptr != '\0'
&& *lineptr != ' '
&& *lineptr != '\t'
&& *lineptr != '\n'
&& *lineptr != '<'
&& *lineptr != '>'
&& *lineptr != '|'
&& *lineptr != '&') {
/* 参数提取至avptr指向的数组avline */
*avptr++ = *lineptr++;
inword = 1;
}
*avptr++ = '\0';
switch(*lineptr) {
case ' ':
case '\t':
j++; //取下一个参数
inword = 0;
break;
case '\n':
case '<':
case '>':
case '|':
case '&':
if(inword == 0) {
cmd[i].args[j] = NULL;
}
return;
default: //for '\0'
return;
}
}
}
/*
* 将lineptr指向的字符串与str进行匹配
* 成功返回1,lineptr移过匹配的字符串
* 失败返回0,lineptr保持不变
*/
int check(const char *str)
{
char *p;
/* 去除空格和制表符 */
while(*lineptr == ' ' || *lineptr == '\t')
lineptr++;
p=lineptr;
while(*str != '\0' && *str == *p) {
str++;
p++;
}
if(*str == '\0') {
lineptr = p; //lineptr移过所匹配的字符串
return 1;
}
/* lineptr保持不变 */
return 0;
}
void get_name(char *name)
{
/* 去除空格和制表符 */
while(*lineptr == ' ' || *lineptr == '\t')
lineptr++;
while(*lineptr != '\0'
&& *lineptr != ' '
&& *lineptr != '\t'
&& *lineptr != '\n'
&& *lineptr != '<'
&& *lineptr != '>'
&& *lineptr != '|'
&& *lineptr != '&') {
*name++ = *lineptr++;
}
*name = '\0';
}
void printf_command()
{
int i;
int j;
printf("cmd_count = %d\n", cmd_count);
if(infile[0] != '\0')
printf("infile = [%s]\n", infile);
if(outfile[0] != '\0')
printf("outfile = [%s]\n", outfile);
for(i=0; i<cmd_count; i++) {
j=0;
while(cmd[i].args[j] != NULL) {
printf("[%s] ",cmd[i].args[j]);
j++;
}
printf("\n");
}
}
C
1
https://gitee.com/icemute/iceshell.git
git@gitee.com:icemute/iceshell.git
icemute
iceshell
iceshell
master

搜索帮助