Пытаюсь написать что-то типа командного интерпретатора.
Сделал основную функцию и лексический анализатор. Щас делаю модуль выполнения команд. При выполнении программы выдаётся сообщение: Segmentation fault. Поправлю в одном месте, вылезет в другом.
Может кто совет даст?
Ниже привожу код (в нём пока нет модуля выполнения команд). Что здесь не так?
/* myshell.c */
/* command interpretator */
#include <stdio.h>
#include <stdlib.h>
/* macros */
#define MAX_STRING_LENGTH 200
#define MAX_TOKENS 100
#define MAX_TOKEN_LENGTH 30
#define MAX_SIMPLE 5
#define MAX_PIPES 5
/* enumerators */
enum { FALSE, TRUE };
enum delimEnum
{
TAB = 1,
PIPE,
SEMICOLON,
END_OF_LINE
};
enum cmdsEnum
{
PWD = 1,
CD,
EXIT
};
enum pipeEnum { READ, WRITE };
/* simple command */
struct simple
{
char *token[MAX_TOKENS]; /* лексемы команды */
int count; /* число лексем */
};
/* pipe */
struct pipeline
{
struct simple simple[MAX_SIMPLE]; /* команд в конвейере */
int count; /* число простых комманд */
};
/* sequence of commands */
struct sequence
{
struct pipeline pipeline[MAX_PIPES]; /* конвееров в последовательности */
int count; /* число конвееров */
};
/* prototips */
struct sequence parseSequence();
struct pipeline parsePipeline();
struct simple parseSimple();
char *nextToken();
char *peekToken();
char *getToken();
/* public */
char *cmds[] = {"pwd", "cd", "exit"};
char *delim[] = {" \t", "|", ";", "\n"};
char line[MAX_STRING_LENGTH]; /* command line */
char tokens[MAX_TOKENS][MAX_TOKEN_LENGTH]; /* лексем в строке */
int tokenCount; /* число лексем в текущей строке */
int tIndex; /* текущая лексема */
int errorFlag; /* TRUE if error */
main(int argc, char *argv[])
{
printf("MyShell>\n");
struct sequence sequence;
/* принимаем и брабатываем команды до <Ctrl>+<D> */
while(TRUE)
{
printf("? ");
if(gets(line) == NULL)
break;
promptline();
errorFlag = FALSE;
if(tokenCount > 1) /* обработать любую непустую строку */
{
sequence = parseSequence(); /* разобрать строку */
if(!errorFlag)
//executeSequence(&sequence); /* выполнить команду (пока нет) */
}
}
return 0;
}
/**************************/
/* лексический анализатор */
/**************************/
int promptline()
{
char *ptr = line; /* указатель на входной буфер */
char token[MAX_TOKEN_LENGTH]; /* текущая лексема */
char *tptr; /* указатель на текущий символ */
tIndex = 0; /* текущая лексема */
/* разбить текущую вхолную строку на лексемы */
while(TRUE)
{
tptr = token;
while(*ptr == ' ') /* пропустить ведущие пробелы */
++ ptr;
if(*ptr == NULL) /* конец строки */
break;
do
{
*tptr++ = *ptr++;
}while(*ptr != ' ' && *ptr != NULL);
*tptr = NULL;
strcpy(tokens[tIndex ++], token);
}
strcpy(tokens[tIndex ++], "\n");
tokenCount = tIndex; /* количество лексем */
tIndex = 0; /* начало списка лексем */
}
/* процедура разбора */
struct sequence parseSequence()
{
struct sequence q;
q.count = 0; /* число конвееров в последовательности */
while(TRUE) /* цикл до ; */
{
q.pipeline[q.count ++] = parsePipeline();
if(peekCode() != SEMICOLON)
break;
nextToken();
}
getToken(END_OF_LINE); /* end of string or not */
return q;
}
struct pipeline parsePipeline()
{
struct pipeline p;
p.count = 0; /* число простых команд в конвеере */
while(TRUE)
{
p.simple[p.count ++] = parseSimple();
if(peekCode() != PIPE)
break;
nextToken();
}
return p;
}
struct simple parseSimple()
{
struct simple s;
s.count = 0; /* число лексем в простой команде */
while(peekCode() == -1)
s.token[s.count ++] = nextToken();
s.token[s.count] = NULL; /* NULL в конце списка лексем */
return s;
}
char *nextToken()
{
return tokens[tIndex ++]; /* вернуть следующую лексему из списка */
}
peekCode()
{
return tokenCode(peekToken()); /* указатель кода следующей лексемы в списке */
}
char *peekToken()
{
return tokens[tIndex]; /* указатель следующей лексемы в списке */
}
char *getToken(code)
int code;
{
char str[MAX_STRING_LENGTH];
if(peekCode() != code)
{
//printf("Expected %s\n", delim[code]);
return NULL;
}
else
return nextToken();
}
tokenCode(token)
char *token;
{
return findtoken(delim, token); /* индекс лексемы в массиве разделителей */
}
int findtoken( strs, str)
char *strs[];
char *str;
{
int i = 0;
/* вернуть индекс строки в строковом массиве strs */
/* или -1, если строки там нет */
while(strcmp(strs[i], "") != 0)
if(strcmp(strs[i], str) == 0)
return i;
else
++ i;
return (-1); /* not found */
}