Example #1
0
static enum ParserResult parsePipeline(struct Parser* parser,
        struct Pipeline* pipeline) {
    pipeline->commands = NULL;
    pipeline->numCommands = 0;
    pipeline->bang = false;

    enum ParserResult result;

    struct Token* token = getToken(parser);
    if (!token) return PARSER_SYNTAX;

    while (token->type == TOKEN && strcmp(token->text, "!") == 0) {
        pipeline->bang = !pipeline->bang;
        parser->offset++;
        token = getToken(parser);
        if (!token) return PARSER_SYNTAX;
    }

    while (true) {
        struct SimpleCommand command;
        result = parseSimpleCommand(parser, &command);
        if (result != PARSER_MATCH) goto fail;

        if (!addToArray((void**) &pipeline->commands, &pipeline->numCommands,
                &command, sizeof(command))) {
            result = PARSER_ERROR;
            goto fail;
        }

        token = getToken(parser);
        if (!token) return PARSER_MATCH;
        if (token->type != OPERATOR || strcmp(token->text, "|") != 0) {
            return PARSER_MATCH;
        }

        parser->offset++;

        token = getToken(parser);
        if (!token) {
            result = PARSER_SYNTAX;
            goto fail;
        }

        while (token->type == OPERATOR && strcmp(token->text, "\n") == 0) {
            parser->offset++;
            token = getToken(parser);
            if (!token) {
                result = PARSER_NEWLINE;
                goto fail;
            }
        }
    }

    return PARSER_MATCH;

fail:
    freePipeline(pipeline);
    return result;
}
Example #2
0
void freePipeline(pipeline* pl)
{
	if(pl->next != NULL)
	{
		freePipeline(pl->next);
	}
	if(pl->command != NULL)
	{
		free(pl->command->args);
		free(pl->command);
	}
	free(pl);
}
Example #3
0
void execTokens(int numTokens, char** tokens)
{
	pipeline* pl = malloc(sizeof(pipeline));
	pl->next = NULL;
	pl->command = NULL; 

	pipeline* lastPipe = pl;

	bool hasFileIn = false;
	int fileIn[2]; // pretends to be a pipe to pass to execSimple
	               // actually just a regular array
	
	bool hasSpecial = false;
	int i;
	for(i = 0; i < numTokens; hasSpecial = false)
	{
		simpleCmd* cmd = malloc(sizeof(simpleCmd));
		cmd->name = tokens[i];

		// allocate enough space for all remaining tokens, plus null terminator
		// this will be more than we need in many cases, but it's easy
		cmd->args = (char**) malloc((numTokens - i + 1) * sizeof(char*));
		int j;
		for(j = 0; j < numTokens - i; j++)
		{
			if (isSpecialToken(tokens[i + j]))
			{
				hasSpecial = true;
				break;
			}
			cmd->args[j] = tokens[i + j];
		}
		i += j; // advances i to the next token to read
		if (hasSpecial)
		{
		specials:
			switch(tokens[i][0])
			{

			// deal w/ special token:
			// '|' -> advance past to next token
			case '|' :
				i++;
				break;
			// '<' -> open file desriptor, set up pipe
			case '<' :
			{
				i++;
				if(i >= numTokens)
				{
					fprintf(stderr, "%s", "quash: syntax error after '<'\n");
					return;
				}
				char* filename = tokens[i];
				int fd = open(filename, O_RDONLY);
				if(fd < 0)
				{
					fprintf(stderr, "quash: could not open file: %s\n", filename);
					return;
				}
				hasFileIn = true;
				fileIn[0]=fd;
				fileIn[1]=fd;				
				i++;
				// should be followed by a special symbol
				// rather than a commaand, so jump to the
				// appropriate place unless we are at the end
				if(i < numTokens)
				{
					goto specials;
				}
				break;
			}
			// '>' -> convert to new builtin (writef)
			case '>' :
				if (tokens[i][1] == '>')
				{
					tokens[i] = "appendf";
				}
				else
				{
					tokens[i] = "writef";
				}
				break;
				// '&' -> ? (deal w/ later? Should only occur at end) : dealt with in main
			}			
		}
		cmd->args[j] = NULL;

		pipeline* nextPipe = malloc(sizeof(pipeline));
		nextPipe->command = cmd;
		nextPipe->next = NULL;
		lastPipe->next = nextPipe;
		lastPipe = nextPipe;
	}
	// drop dummy block, pass null for stdin
	runPipeline(pl->next, hasFileIn ? fileIn : NULL);
	freePipeline(pl);
	if(hasFileIn)
	{
		close(fileIn[0]);
	}
}
Example #4
0
void freeCompleteCommand(struct CompleteCommand* command) {
    freePipeline(&command->pipeline);
}