aboutsummaryrefslogblamecommitdiffstats
path: root/common.h
blob: b5def372a8dce5a00d47f58c0dac8377fb625e14 (plain) (tree)



























































































































































                                                                                                                          
/* See LICENSE file for copyright and license details. */
#include <libsimple.h>
#include <libsimple-arg.h>
#include "config.h"


enum argument_type {
	/* .text and .length */
	QUOTED, /* \ or '…' or $'…' */
	UNQUOTED, /* normal */
	/* .child */
	QUOTE_EXPRESSION, /* "…" */
	BACKQUOTE_EXPRESSION, /* `…` */
	ARITHMETIC_EXPRESSION, /* $((…)) */
	VARIABLE_SUBSTITUTION, /* ${…} */
	SUBSHELL_SUBSTITUTION, /* $(…) */
	PROCESS_SUBSTITUTION_INPUT, /* >(…) */
	PROCESS_SUBSTITUTION_OUTPUT, /* <(…) */
	PROCESS_SUBSTITUTION_INPUT_OUTPUT, /* <>(…) */
	SUBSHELL, /* (…) ## if non-first argument: format shell code into a string (can be used for a clean subshell) */
	ARITHMETIC_SUBSHELL, /* ((…)) ## if non-first argument: format shell code into a string */
	/* (none) */
	REDIRECTION, /* at beginning of argument, use next redirection and use reminder of argument as right-hand side */
	FUNCTION_MARK /* () */
};

enum redirection_type {
	REDIRECT_INPUT,
	REDIRECT_INPUT_TO_FD,
	REDIRECT_OUTPUT,
	REDIRECT_OUTPUT_APPEND,
	REDIRECT_OUTPUT_CLOBBER,
	REDIRECT_OUTPUT_TO_FD,
	REDIRECT_OUTPUT_AND_STDERR,
	REDIRECT_OUTPUT_AND_STDERR_APPEND,
	REDIRECT_OUTPUT_AND_STDERR_CLOBBER,
	REDIRECT_OUTPUT_AND_STDERR_TO_FD,
	REDIRECT_INPUT_OUTPUT,
	REDIRECT_INPUT_OUTPUT_TO_FD,
	HERE_STRING,
	HERE_DOCUMENT,
	HERE_DOCUMENT_INDENTED
};

enum tokeniser_mode {
	NORMAL_MODE,
	COMMENT_MODE,
	BQ_QUOTE_MODE,
	DQ_QUOTE_MODE,
	RRB_QUOTE_MODE,
	RB_QUOTE_MODE,
	SB_QUOTE_MODE,
	CB_QUOTE_MODE,
	HERE_DOCUMENT_MODE
};

enum command_terminal {
	DOUBLE_SEMICOLON,
	SEMICOLON,
	AMPERSAND,
	SOCKET_PIPE,
	PIPE,
	PIPE_AMPERSAND,
	AND,
	OR
};

struct parser_state;

struct argument {
	enum argument_type type;
	union {
		struct {
			char *text;
			size_t length;
		};
		struct parser_state *child;
	};
	size_t line_number;
	struct argument *next_part;
};

struct redirection {
	enum redirection_type type;
	struct argument *left_hand_side;
};

struct command {
	enum command_terminal terminal;
	struct argument **arguments;
	size_t narguments;
	struct redirection **redirections;
	size_t nredirections;
};

struct parser_state {
	struct parser_state *parent;
	struct command **commands;
	size_t ncommands;
	struct argument **arguments;
	size_t narguments;
	struct redirection **redirections;
	size_t nredirections;
	struct argument *current_argument;
	struct argument *current_argument_end;
	char need_right_hand_side;
};

struct here_document {
	struct redirection *redirection;
	struct argument *argument;
	struct here_document *next;
};

struct mode_stack {
	enum tokeniser_mode mode;
	int she_is_comment;
	struct mode_stack *previous;
};

struct parser_context {
	int tty_input;
	int end_of_file_reached;
	int premature_end_of_file;
	size_t preparser_offset;
	size_t preparser_line_number;
	size_t line_continuations;
	size_t tokeniser_line_number;
	struct mode_stack *mode_stack;
	struct parser_state *parser_state;
	struct here_document *here_documents_first;
	struct here_document **here_documents_next;
};


/* apsh.c */
void initialise_parser_context(struct parser_context *ctx);

/* preparser.c */
size_t parse(struct parser_context *ctx, char *code, size_t code_len, size_t *nremovedp);

/* tokeniser.c */
void push_mode(struct parser_context *ctx, enum tokeniser_mode mode);
void pop_mode(struct parser_context *ctx);
size_t parse_preparsed(struct parser_context *ctx, char *code, size_t code_len);

/* parser.c */
void push_end_of_file(struct parser_context *ctx);
void push_whitespace(struct parser_context *ctx, int strict);
void push_semicolon(struct parser_context *ctx, int maybe);
size_t push_symbol(struct parser_context *ctx, char *token, size_t token_len);
void push_quoted(struct parser_context *ctx, char *text, size_t text_len);
void push_escaped(struct parser_context *ctx, char *text, size_t text_len);
void push_unquoted(struct parser_context *ctx, char *text, size_t text_len);
void push_enter(struct parser_context *ctx, enum argument_type type);
void push_leave(struct parser_context *ctx);