Beispiel #1
0
accept_t lexer_read_variable(struct lexer_book * bk, struct token * name)
{
    lexer_discard_white_space(bk);

    if(lexer_next_peek(bk) == '=') {
        lexer_next_char(bk);
        lexer_add_to_lexeme(bk, '=');
    } else {
        int c = lexer_next_char(bk);
        if(lexer_next_peek(bk) != '=')
            return NO;
        lexer_add_to_lexeme(bk, c);
        lexer_next_char(bk);	/* Jump = */
    }

    lexer_push_token(bk, lexer_pack_token(bk, VARIABLE));
    lexer_push_token(bk, name);

    lexer_discard_white_space(bk);

    lexer_read_expandable(bk, '\n');
    lexer_roll_back(bk, 1);	//Recover '\n'

    lexer_discard_white_space(bk);

    if(lexer_next_char(bk) != '\n')
        return NO;

    return YES;
}
Beispiel #2
0
int lexer_read_variable(struct lexer *lx, struct token *name)
{
	lexer_discard_white_space(lx);

	if(lexer_next_peek(lx) == '=') {
		lexer_next_char(lx);
		lexer_add_to_lexeme(lx, '=');
	} else {
		int c = lexer_next_char(lx);
		if(lexer_next_peek(lx) != '=')
			lexer_report_error(lx, "Missing = in variable definition.");
		lexer_add_to_lexeme(lx, c);
		lexer_next_char(lx);	/* Jump = */
	}

	lexer_push_token(lx, lexer_pack_token(lx, TOKEN_VARIABLE));
	lexer_push_token(lx, name);

	lexer_discard_white_space(lx);

	//Read variable value
	lexer_push_token(lx, lexer_read_expandable(lx, '\n'));
	lexer_roll_back(lx, 1);	//Recover '\n'

	lexer_discard_white_space(lx);

	if(lexer_next_char(lx) != '\n')
		lexer_report_error(lx, "Missing newline at end of variable definition.");

	return 1;
}
Beispiel #3
0
accept_t lexer_read_line(struct lexer_book * bk)
{
    char c = lexer_next_peek(bk);

    int colon, equal;

    bk->substitution_mode = ROOT;

    switch (c) {
    case CHAR_EOF:
        /* Found end of file */
        lexer_next_char(bk);
        return YES;
        break;
    case '#':
        lexer_discard_comments(bk);
        return YES;
        break;
    case '\t':
        bk->substitution_mode = COMMAND;
        return lexer_read_command(bk);
        break;
    case ' ':
        /* Eat whitespace and try again */
        lexer_discard_white_space(bk);
        return lexer_read_line(bk);
        break;
    case '\n':
        /* Ignore empty lines and try again */
        lexer_next_char(bk);
        return lexer_read_line(bk);
        break;
    case '@':
        /* Jump @ */
        bk->substitution_mode = SYNTAX;
        lexer_next_char(bk);
        return lexer_read_syntax(bk);
        break;
    default:
        /* Either makeflow keyword (e.g. export), a file list, or variable assignment */
        lexer_discard_white_space(bk);

        colon = lexer_unquoted_look_ahead_count(bk, ":");
        equal = lexer_unquoted_look_ahead_count(bk, "=");

        fprintf(stderr, "%d %d %c\n", colon, equal, c);


        if((colon != -1) && (equal == -1 || colon < equal)) {
            bk->substitution_mode = FILES;
            return lexer_read_file_list(bk);
        } else {
            bk->substitution_mode = SYNTAX;
            return lexer_read_syntax(bk);
        }
        break;
    }

}
Beispiel #4
0
struct list *lexer_read_command_aux(struct lexer *lx)
{
	int spaces_deleted = lexer_discard_white_space(lx);

	struct list *tokens = list_create();

	//Preserve space in substitutions.
	if(spaces_deleted && lx->depth > 0) {
		list_push_tail(tokens, lexer_pack_token(lx, TOKEN_SPACE));
	}

	/* Read all command tokens. Note that we read from lx, but put in lx_c. */
	while(1) {
		struct token *t = lexer_read_command_argument(lx);
		if(!t)
			break;

		if(t->type == TOKEN_SUBSTITUTION) {
			tokens = list_splice(tokens, lexer_expand_substitution(lx, t, lexer_read_command_aux));
			lexer_free_token(t);
			continue;
		} else {
			list_push_tail(tokens, t);
			if(t->type==TOKEN_NEWLINE) break;
		}
	}

	return tokens;
}
Beispiel #5
0
accept_t lexer_read_file_list(struct lexer_book *bk)
{
    int count = 0;

    lexer_discard_white_space(bk);

    struct token *t;
    do {
        t = lexer_read_file(bk);
        if(t->type == NEWLINE && count == 0) {
            return NO;
        } else if(t->type != NEWLINE && count == 0) {
            /* Add file list start marker */
            lexer_push_token(bk, lexer_pack_token(bk, FILES));
        }

        lexer_push_token(bk, t);
        count++;
    } while(t->type != NEWLINE);

    if(count > 1)
        return YES;
    else {
        return NO;
    }
}
Beispiel #6
0
accept_t lexer_read_command(struct lexer_book *bk)
{
    if(lexer_next_peek(bk) != '\t')
        return NO;

    int count = 0;

    lexer_discard_white_space(bk);

    struct token *t;
    do {
        t = lexer_read_command_argument(bk);
        if(!t)
            break;
        if(t->type == NEWLINE && count == 0) {
            lexer_report_error(bk, "Missing command line.\n");
        } else if(t->type != NEWLINE && count == 0) {
            /* Add command start marker */
            lexer_push_token(bk, lexer_pack_token(bk, COMMAND));
        }
        lexer_push_token(bk, t);
        count++;
    } while(t->type != NEWLINE);

    if(count > 1)
        return YES;
    else {
        return NO;
    }
}
Beispiel #7
0
int lexer_read_expandable_recursive(struct lexer_book *bk, char end_marker)
{
    int count = 0;
    lexer_discard_white_space(bk);

    while(!bk->eof) {
        int c = lexer_next_peek(bk);

        if(c == '$') {
            count++;
            lexer_push_token(bk, lexer_read_substitution(bk));
        }
        if(c == '\'') {
            lexer_read_literal(bk);
            lexer_push_token(bk, lexer_pack_token(bk, LITERAL));
        } else if(c == end_marker) {
            lexer_next_char(bk);	/* Jump end_marker */
            return count;
        } else if(c == '"')
            count += lexer_read_expandable_recursive(bk, '"');
        else if(c == '#' && end_marker != '"') {
            lexer_discard_comments(bk);
            return count;
        } else {
            count++;
            lexer_push_token(bk, lexer_read_literal_in_expandable_until(bk, end_marker));
        }
    }
    /* Found eof before end_marker */
    abort();
}
Beispiel #8
0
struct token *lexer_read_file(struct lexer *lx)
{
	int c = lexer_next_peek(lx);

	switch (c) {
	case CHAR_EOF:
		lx->lexeme_end++;
		lx->eof = 1;
		if(lx->depth == 0)
			lexer_report_error(lx, "Found end of file while completing file list.\n");
		return NULL;
		break;
	case '\n':
		lexer_next_char(lx);	/* Jump \n */
		lexer_add_to_lexeme(lx, c);
		return lexer_pack_token(lx, TOKEN_NEWLINE);
		break;
	case '#':
		lexer_discard_comments(lx);
		lexer_add_to_lexeme(lx, '\n');
		return lexer_pack_token(lx, TOKEN_NEWLINE);
	case ':':
		lexer_next_char(lx);	/* Jump : */
		return lexer_pack_token(lx, TOKEN_COLON);
		break;
	case ' ':
	case '\t':
		/* Discard white-space and add space token. */
		lexer_discard_white_space(lx);
		return lexer_pack_token(lx, TOKEN_SPACE);
		break;
	case '$':
		return lexer_read_substitution(lx);
		break;
	case '\'':
		lexer_add_to_lexeme(lx, '\'');
		lexer_read_literal_quoted(lx);
		lexer_add_to_lexeme(lx, '\'');
		return lexer_pack_token(lx, TOKEN_LITERAL);
		break;
	case '-':
		if(lexer_peek_remote_rename_syntax(lx)) {
			lexer_next_char(lx);	/* Jump -> */
			lexer_next_char(lx);
			return lexer_pack_token(lx, TOKEN_REMOTE_RENAME);
		}
		/* Else fall through */
	default:
		return lexer_read_filename(lx);
		break;
	}
}
Beispiel #9
0
int lexer_read_line(struct lexer * lx)
{
	char c = lexer_next_peek(lx);

	int colon, equal;

	switch (c) {
	case CHAR_EOF:
		/* Found end of file */
		return lexer_next_char(lx);
		break;
	case '#':
		lexer_discard_comments(lx);
		return 1;
		break;
	case '\t':
		return lexer_read_command(lx);
		break;
	case '\n':
		/* Ignore empty lines and try again */
		lexer_next_char(lx);
		return lexer_read_line(lx);
		break;
	case '@':
		/* Jump @ */
		lexer_next_char(lx);
		return lexer_read_syntax_or_variable(lx);
		break;
	default:
		/* Either makeflow keyword (e.g. export), a file list, or variable assignment */
		lexer_discard_white_space(lx);

		colon = lexer_unquoted_look_ahead_count(lx, ":");
		equal = lexer_unquoted_look_ahead_count(lx, "=");

		/* If there is a colon and it appears before any existing
		 * equal sign read the line as a file list. */
		if((colon != -1) && (equal == -1 || colon < equal)) {
			lexer_read_file_list(lx);
		}
		else if(c == ' ' && equal == -1) {
			/* A command starting with a space.. for backwards compatibility. */
			return lexer_read_command(lx);
		}
		else {
			lexer_read_syntax_or_variable(lx);
		}

		return 1;
		break;
	}
}
Beispiel #10
0
struct token *lexer_read_file(struct lexer_book *bk)
{
	int c = lexer_next_peek(bk);

	switch(c)
	{
	case CHAR_EOF:
		lexer_report_error(bk, "Found end of file while completing file list.\n");
		return NULL;
		break;
	case '\n' :
		lexer_next_char(bk);           /* Jump \n */
		lexer_add_to_lexeme(bk, c);
		return lexer_pack_token(bk, NEWLINE);
		break;
	case '#' :
		lexer_discard_comments(bk);
		lexer_add_to_lexeme(bk, '\n');
		return lexer_pack_token(bk, NEWLINE);
	case ':' :
		lexer_next_char(bk);           /* Jump : */
		return lexer_pack_token(bk, COLON);
		break;
	case ' ' :
	case '\t':
		/* Discard white-space and try again */
		lexer_discard_white_space(bk);
		return lexer_read_file(bk);
		break;
	case '$'  :
		return lexer_read_substitution(bk);
		break;
	case '\'':
		lexer_add_to_lexeme(bk, '\'');
		lexer_read_literal_quoted(bk);
		lexer_add_to_lexeme(bk, '\'');
		return lexer_pack_token(bk, LITERAL);
		break;
	case '-' :
		if( lexer_peek_remote_rename_syntax(bk) )
		{
			lexer_next_char(bk);           /* Jump -> */
			lexer_next_char(bk);           
			return lexer_pack_token(bk, REMOTE_RENAME);
		}
		/* Else fall through */
	default:
		return lexer_read_filename(bk);
		break;
	}
}
Beispiel #11
0
accept_t lexer_read_syntax(struct lexer_book * bk)
{
    lexer_discard_white_space(bk);
    struct token *name = lexer_read_syntax_name(bk);

    if(strcmp("export", name->lexeme) == 0)
        return lexer_read_syntax_export(bk, name);
    else if(lexer_unquoted_look_ahead_count(bk, "=") > -1)
        return lexer_read_variable(bk, name);
    else {
        lexer_roll_back(bk, strlen(name->lexeme));
        lexer_report_error(bk, "Unrecognized keyword: %s.", name->lexeme);
    }

    return NO;
}
Beispiel #12
0
accept_t lexer_read_syntax_export(struct lexer_book *bk, struct token *name)
{
    lexer_discard_white_space(bk);

    name->type = SYNTAX;
    lexer_push_token(bk, name);

    if(lexer_unquoted_look_ahead_count(bk, "=") > -1)
        return lexer_read_variable(bk, lexer_read_syntax_name(bk));
    else
        return lexer_read_variable_list(bk);



    return YES;
}
Beispiel #13
0
int lexer_read_syntax_or_variable(struct lexer * lx)
{
	lexer_discard_white_space(lx);
	struct token *name = lexer_read_syntax_name(lx);

	if(strcmp("export", name->lexeme) == 0)
		return lexer_read_syntax_export(lx, name);
	else if(lexer_unquoted_look_ahead_count(lx, "=") > -1)
		return lexer_read_variable(lx, name);
	else {
		lexer_roll_back(lx, strlen(name->lexeme));
		lexer_report_error(lx, "Unrecognized keyword: %s.", name->lexeme);
	}

	return 1;
}
Beispiel #14
0
int lexer_read_syntax_export(struct lexer *lx, struct token *name)
{
	lexer_discard_white_space(lx);

	//name->lexeme is "export"
	name->type = TOKEN_SYNTAX;
	lexer_push_token(lx, name);

	if(lexer_unquoted_look_ahead_count(lx, "=") > -1)
		lexer_read_variable(lx, lexer_read_syntax_name(lx));
	else
		lexer_read_variable_list(lx);

	lexer_push_token(lx, lexer_pack_token(lx, TOKEN_NEWLINE));

	return 1;
}
Beispiel #15
0
/* Consolidates a sequence of white space into a single SPACE token */
struct token *lexer_read_white_space(struct lexer *lx)
{
	int count = lexer_discard_white_space(lx);

	while(strchr(WHITE_SPACE, lexer_next_peek(lx))) {
		count++;
		lexer_next_char(lx);
	}

	if(count > 0) {
		lexer_add_to_lexeme(lx, ' ');
		return lexer_pack_token(lx, TOKEN_SPACE);
	} else
		lexer_report_error(lx, "Expecting white space.");

	return NULL;
}
Beispiel #16
0
int lexer_read_variable_list(struct lexer * lx)
{
	int c;

	while((c = lexer_next_peek(lx)) != '\n') {
		lexer_discard_white_space(lx);
		if(c == '#') {
			lexer_discard_comments(lx);
			lexer_roll_back(lx, 1);	//Recover the newline
			break;
		}

		lexer_push_token(lx, lexer_read_syntax_name(lx));
	}

	lexer_add_to_lexeme(lx, lexer_next_char(lx));	//Drop the newline
	lexer_push_token(lx, lexer_pack_token(lx, TOKEN_NEWLINE));

	return 1;
}
Beispiel #17
0
accept_t lexer_read_variable_list(struct lexer_book * bk)
{
    int c;

    while((c = lexer_next_peek(bk)) != '\n') {
        lexer_discard_white_space(bk);
        if(c == '#') {
            lexer_discard_comments(bk);
            lexer_roll_back(bk, 1);	//Recover the newline
            break;
        }

        lexer_push_token(bk, lexer_read_syntax_name(bk));

    }

    lexer_add_to_lexeme(bk, lexer_next_char(bk));	//Drop the newline
    lexer_push_token(bk, lexer_pack_token(bk, NEWLINE));

    return YES;
}
Beispiel #18
0
//opened tracks whether it is the opening (opened = 0) or closing (opened = 1) double quote we encounter.
struct list *lexer_read_expandable_recursive(struct lexer *lx, char end_marker, int opened)
{
	lexer_discard_white_space(lx);

	struct list *tokens = list_create();

	while(!lx->eof) {
		int c = lexer_next_peek(lx);

		if(c == '$') {
			list_push_tail(tokens, lexer_read_substitution(lx));
		}

		if(c == '\'') {
			lexer_read_literal(lx);
			list_push_tail(tokens, lexer_pack_token(lx, TOKEN_LITERAL));
		} else if(c == '"' && opened == 0) {
				lexer_add_to_lexeme(lx, lexer_next_char(lx));
				list_push_tail(tokens, lexer_pack_token(lx, TOKEN_LITERAL));     // Add first "
				tokens = list_splice(tokens, lexer_read_expandable_recursive(lx, '"', 1));
				lexer_add_to_lexeme(lx, '"');
				list_push_tail(tokens, lexer_pack_token(lx, TOKEN_LITERAL));     // Add closing "
				if(end_marker == '"')
					return tokens;
		} else if(c == '#' && end_marker != '"') {
			lexer_discard_comments(lx);
		} else if(c == end_marker) {
			lexer_next_char(lx);	/* Jump end_marker */
			return tokens;
		} else {
			list_push_tail(tokens, lexer_read_literal_in_expandable_until(lx, end_marker));
		}
	}

	lexer_report_error(lx, "Found EOF before end marker: %c.\n", end_marker);

	return NULL;
}
Beispiel #19
0
struct list *lexer_read_file_list_aux(struct lexer *lx)
{
	struct list *tokens = list_create();

	lexer_discard_white_space(lx);

	while(1) {
		struct token *t = lexer_read_file(lx);
		if(!t) break;

		//Do substitution recursively
		if(t->type == TOKEN_SUBSTITUTION) {
			tokens = list_splice(tokens, lexer_expand_substitution(lx, t, lexer_read_file_list_aux));
			lexer_free_token(t);
			continue;
		} else {
			list_push_tail(tokens, t);
			if(t->type==TOKEN_NEWLINE) break;
		}
	}

	return tokens;
}