text:
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <stdlib.h>
#include "regex_engine.h"

/*

LL grammar for the regexes that the regex compiler supports:

hex_digit
	0-9
	A-F
	a-f

escapable_character
	'\'
	'n'
	't'
	's'
	'('
	')'
	'['
	']'
	'+'
	'?'
	'*'
	'.'
	'-'
	'^'
	'x' hex_digit hex_digit

escaped_character
	'\' escapable_character

character_range
	non_class_character '-' non_class_character

non_class_character
	escaped_character
	' ' to '''
	','
	'/' to '>'
	'@' to 'Z'
	'_' to '{'
	'}' to '~'

character_or_range
	character_range
	non_class_character
	'.'

character_or_class
	character_class
	non_class_character
	'.'

character_class_rest
	character_or_range character_class_rest
	']'

character_class
	'[' character_or_range character_class_rest
	'[' '^' character_or_range character_class_rest

character_sequence_rest
	character_or_class character_sequence_rest
	epsilon

character_sequence
	character_or_class character_sequence_rest

postfix_operator
	'?'
	'+'
	'*'

infix_expression_rest
	'|' regular_expression infix_expression_rest
	')'

infix_expression
	'(' regular_expression infix_expression_rest

postfix_expression
	character_sequence postfix_operation
	character_sequence
	infix_expression postfix_operation
	infix_expression

regular_expression
	postfix_expression regular_expression
	epsilon

*/

static struct regex_parser_node * postfix_operator(struct regex_compiler_state *);
static struct regex_parser_node * regex_postfix_expression(struct regex_compiler_state *);
static struct regex_parser_node * infix_expression_rest(struct regex_compiler_state *);
static struct regex_parser_node * infix_expression(struct regex_compiler_state *);
static struct regex_parser_node * regular_expression(struct regex_compiler_state *);
static struct regex_parser_node * character_sequence(struct regex_compiler_state *);
static struct regex_parser_node * character_or_range(struct regex_compiler_state *);
static struct regex_parser_node * character_or_class(struct regex_compiler_state *);
static struct regex_parser_node * escapable_character(struct regex_compiler_state *);
static struct regex_parser_node * escaped_character(struct regex_compiler_state *);
static struct regex_parser_node * character_range(struct regex_compiler_state *);
static struct regex_parser_node * character_class(struct regex_compiler_state *);
static struct regex_parser_node * non_class_character(struct regex_compiler_state *);

static struct regex_computation_node * reg_postfix_expression(struct regex_compiler_state *, struct regex_parser_node *, struct regex_computation_node *);
static struct regex_computation_node * reg_infix_expression(struct regex_compiler_state *, struct regex_parser_node *, struct regex_computation_node *);
static struct regex_computation_node * reg_regular_expression(struct regex_compiler_state *, struct regex_parser_node *, struct regex_computation_node *);
static void explain_error(struct regex_compiler_state *);
static void regex_matcher_state_optimize(struct regex_matcher_state *, unsigned char);
static void regex_compiler_state_parse(struct regex_compiler_state *);

static void destroy_errors(struct regex_compiler_error * n);
static void destroy_regex_computation_nodes(struct regex_compiler_state *, struct regex_computation_node *);

void regex_compiler_state_create(struct regex_compiler_state * state, struct memory_pool_collection * m, unsigned char * buffer, unsigned int id){
	state->m = m;
	state->position = 0;
	state->buffer = buffer;
	state->top_node = (struct regex_parser_node *)0;
	state->buffer_length = (unsigned int)strlen((char *)buffer);
	state->errors = (struct regex_compiler_error *)0;
	state->match_id = id;
}

static struct regex_parser_node * create_regex_parser_node(struct regex_compiler_state * state, struct regex_parser_node * n, struct regex_parser_node * f, unsigned char c, enum regex_parser_node_type t){
	struct regex_parser_node * new_node = struct_regex_parser_node_memory_pool_malloc(state->m);
	new_node->next = n;
	new_node->first_child = f;
	new_node->type = t;
	new_node->c = c;
	return new_node;
}

static void destroy_regex_parser_node_tree(struct regex_compiler_state * state, struct regex_parser_node * n){
	if(n){
		destroy_regex_parser_node_tree(state, n->next);
		destroy_regex_parser_node_tree(state, n->first_child);
		struct_regex_parser_node_memory_pool_free(state->m, n);
	}
}

void regex_compiler_state_destroy(struct regex_compiler_state * state){
	destroy_regex_parser_node_tree(state, state->top_node);
	destroy_regex_computation_nodes(state, state->first_computation_node);
	destroy_errors(state->errors);
}

static struct regex_parser_node * regex_accept_range(struct regex_compiler_state * state, unsigned char low, unsigned char high){
	if(state->position < state->buffer_length){
		if((state->buffer[state->position] >= low) && (state->buffer[state->position] <= high)){
			unsigned char c = state->buffer[state->position];
			state->position += 1;
			return create_regex_parser_node(state, (struct regex_parser_node *)0, (struct regex_parser_node *)0, c, REGEX_TERMINAL);
		}
	}
	return (struct regex_parser_node *)0;
}

static void set_error_state(struct regex_compiler_state * state, enum regex_compiler_error_type t){
	struct regex_compiler_error * er = (struct regex_compiler_error *)malloc(sizeof(struct regex_compiler_error));
	er->next = (struct regex_compiler_error *)0;
	er->type = t;
	er->character_index_of_error = state->position;
	if(state->errors){
		struct regex_compiler_error * c = state->errors;
		while(c->next) {
			c = c->next;
		}
		c->next = er; /*  Add it to the end */
	}else{
		state->errors = er; /*  First one */
	}
}

static struct regex_parser_node * regex_accept(struct regex_compiler_state * state, unsigned char c){
	return regex_accept_range(state, c, c);
}

static struct regex_parser_node * regex_make_epsilon(struct regex_compiler_state * state){
	return create_regex_parser_node(state, (struct regex_parser_node *)0, (struct regex_parser_node *)0, 0, REGEX_EPSILON);
}

static struct regex_parser_node * regex_hex_digit(struct regex_compiler_state * state){
	struct regex_parser_node * n = (struct regex_parser_node *)0;
	if(state->errors){ return n; }
	if((n = regex_accept_range(state, '0', '9'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_HEX_DIGIT);
	}else if((n = regex_accept_range(state, 'A', 'F'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_HEX_DIGIT);
	}else if((n = regex_accept_range(state, 'a', 'f'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_HEX_DIGIT);
	}else{
		return (struct regex_parser_node *)0;
	}
}

static struct regex_parser_node * escapable_character(struct regex_compiler_state * state){
	struct regex_parser_node * n = (struct regex_parser_node *)0;
	if(state->errors){ return n; }
	if((n = regex_accept(state, 'n'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_ESCAPABLE_CHARACTER);
	}else if((n = regex_accept(state, 't'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_ESCAPABLE_CHARACTER);
	}else if((n = regex_accept(state, '('))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_ESCAPABLE_CHARACTER);
	}else if((n = regex_accept(state, ')'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_ESCAPABLE_CHARACTER);
	}else if((n = regex_accept(state, '['))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_ESCAPABLE_CHARACTER);
	}else if((n = regex_accept(state, ']'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_ESCAPABLE_CHARACTER);
	}else if((n = regex_accept(state, '+'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_ESCAPABLE_CHARACTER);
	}else if((n = regex_accept(state, '?'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_ESCAPABLE_CHARACTER);
	}else if((n = regex_accept(state, '*'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_ESCAPABLE_CHARACTER);
	}else if((n = regex_accept(state, '.'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_ESCAPABLE_CHARACTER);
	}else if((n = regex_accept(state, '-'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_ESCAPABLE_CHARACTER);
	}else if((n = regex_accept(state, '^'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_ESCAPABLE_CHARACTER);
	}else if((n = regex_accept(state, '|'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_ESCAPABLE_CHARACTER);
	}else if((n = regex_accept(state, '\\'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_ESCAPABLE_CHARACTER);
	}else if((n = regex_accept(state, 'x'))){ /*  Escaped hex character */
		if((n->next = regex_hex_digit(state))){
			if((n->next->next = regex_hex_digit(state))){
				return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_ESCAPABLE_CHARACTER);
			}else{
				set_error_state(state, REGEX_ERROR_EXPECTED_HEX_DIGIT);
				destroy_regex_parser_node_tree(state, n);
				return (struct regex_parser_node *)0;
			}
		}else{
			set_error_state(state, REGEX_ERROR_EXPECTED_HEX_DIGIT);
			destroy_regex_parser_node_tree(state, n);
			return (struct regex_parser_node *)0;
		}
	}else{
		return (struct regex_parser_node *)0;
	}
}

static struct regex_parser_node * escaped_character(struct regex_compiler_state * state){
	struct regex_parser_node * n = (struct regex_parser_node *)0;
	if(state->errors){ return n; }
	if((n = regex_accept(state, '\\'))){
		if((n->next = escapable_character(state))){
			return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_ESCAPED_CHARACTER);
		}else{
			set_error_state(state, REGEX_ERROR_NOT_ESCAPABLE);
			destroy_regex_parser_node_tree(state, n);
			return (struct regex_parser_node *)0;
		}
	}else{
		return (struct regex_parser_node *)0;
	}
}

static struct regex_parser_node * character_range(struct regex_compiler_state * state){
	struct regex_parser_node * n = (struct regex_parser_node *)0;
	unsigned int previous_position = state->position;
	if(state->errors){ return n; }
	if((n = non_class_character(state))){
		if((n->next = regex_accept(state, '-'))){
			if((n->next->next = non_class_character(state))){
				return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_CHARACTER_RANGE);
			}else{
				set_error_state(state, REGEX_ERROR_INVALID_CHARACTER_RANGE);
				destroy_regex_parser_node_tree(state, n);
				return (struct regex_parser_node *)0;
			}
		}else{
			/*  Need to backtrack... */
			state->position = previous_position;
			destroy_regex_parser_node_tree(state, n);
			return (struct regex_parser_node *)0;
		}
	}else{
		return (struct regex_parser_node *)0;
	}
}

static struct regex_parser_node * character_or_range(struct regex_compiler_state * state){
	struct regex_parser_node * n = (struct regex_parser_node *)0;
	if(state->errors){ return n; }
	if((n = character_range(state))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_CHARACTER_OR_RANGE);
	}else if((n = non_class_character(state))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_CHARACTER_OR_RANGE);
	}else if((n = regex_accept(state, '.'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_CHARACTER_OR_RANGE);
	}else{
		return (struct regex_parser_node *)0;
	}
}

static struct regex_parser_node * character_or_class(struct regex_compiler_state * state){
	struct regex_parser_node * n = (struct regex_parser_node *)0;
	if(state->errors){ return n; }
	if((n = character_class(state))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_CHARACTER_OR_CLASS);
	}else if((n = non_class_character(state))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_CHARACTER_OR_CLASS);
	}else if((n = regex_accept(state, '.'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_CHARACTER_OR_CLASS);
	}else{
		return (struct regex_parser_node *)0;
	}
}

static struct regex_parser_node * character_class_rest(struct regex_compiler_state * state){
	struct regex_parser_node * n = (struct regex_parser_node *)0;
	if(state->errors){ return n; }
	if((n = character_or_range(state))){
		if((n->next = character_class_rest(state))){
			return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_CHARACTER_CLASS_REST);
		}else{
			set_error_state(state, REGEX_ERROR_INVALID_CHARACTER_CLASS);
			destroy_regex_parser_node_tree(state, n);
			return (struct regex_parser_node *)0;
		}
	}else if((n = regex_accept(state, ']'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_CHARACTER_CLASS_REST);
	}else{
		return (struct regex_parser_node *)0;
	}
}

static struct regex_parser_node * character_class(struct regex_compiler_state * state){
	struct regex_parser_node * n = (struct regex_parser_node *)0;
	if(state->errors){ return n; }
	if((n = regex_accept(state, '['))){
		if((n->next = regex_accept(state, '^'))){
			if((n->next->next = character_or_range(state))){
				if((n->next->next->next = character_class_rest(state))){
					return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_CHARACTER_CLASS);
				}else{
					set_error_state(state, REGEX_ERROR_INVALID_CHARACTER_CLASS);
					destroy_regex_parser_node_tree(state, n);
					return (struct regex_parser_node *)0;
				}
			}else{
				set_error_state(state, REGEX_ERROR_INVALID_CHARACTER_CLASS);
				destroy_regex_parser_node_tree(state, n);
				return (struct regex_parser_node *)0;
			}
		}else if((n->next = character_or_range(state))){
			if((n->next->next = character_class_rest(state))){
				return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_CHARACTER_CLASS);
			}else{
				set_error_state(state, REGEX_ERROR_INVALID_CHARACTER_CLASS);
				destroy_regex_parser_node_tree(state, n);
				return (struct regex_parser_node *)0;
			}
		}else{
			set_error_state(state, REGEX_ERROR_INVALID_CHARACTER_CLASS);
			destroy_regex_parser_node_tree(state, n);
			return (struct regex_parser_node *)0;
		}
	}else{
		return (struct regex_parser_node *)0;
	}
}

static struct regex_parser_node * non_class_character(struct regex_compiler_state * state){
	struct regex_parser_node * n = (struct regex_parser_node *)0;
	if(state->errors){ return n; }
	if((n = escaped_character(state))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_NON_CLASS_CHARACTER);
	/*  Normal characters:  Ranges carefully created to avoid special control characters */
	}else if((n = regex_accept_range(state, ' ', '\''))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_NON_CLASS_CHARACTER);
	}else if((n = regex_accept(state, ','))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_NON_CLASS_CHARACTER);
	}else if((n = regex_accept_range(state, '/', '>'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_NON_CLASS_CHARACTER);
	}else if((n = regex_accept_range(state, '@', 'Z'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_NON_CLASS_CHARACTER);
	}else if((n = regex_accept_range(state, '_', '{'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_NON_CLASS_CHARACTER);
	}else if((n = regex_accept_range(state, '}', '~'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_NON_CLASS_CHARACTER);
	}else{
		return (struct regex_parser_node *)0;
	}
}

static struct regex_parser_node * character_sequence_rest(struct regex_compiler_state * state){
	struct regex_parser_node * n = (struct regex_parser_node *)0;
	if(state->errors){ return n; }
	if((n = character_or_class(state))){
		if((n->next = character_sequence_rest(state))){
			return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_CHARACTER_SEQUENCE_REST);
		}else{
			set_error_state(state, REGEX_ERROR_INVALID_CHARACTER_SEQUENCE);
			destroy_regex_parser_node_tree(state, n);
			return (struct regex_parser_node *)0;
		}
	}else{
		if(state->errors){ return n; }
		return create_regex_parser_node(state, (struct regex_parser_node *)0, regex_make_epsilon(state), 0, REGEX_CHARACTER_SEQUENCE_REST);
	}
}

static struct regex_parser_node * character_sequence(struct regex_compiler_state * state){
	struct regex_parser_node * n = (struct regex_parser_node *)0;
	if(state->errors){ return n; }
	if((n = character_or_class(state))){
		if((n->next = character_sequence_rest(state))){
			return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_CHARACTER_SEQUENCE);
		}else{
			set_error_state(state, REGEX_ERROR_INVALID_CHARACTER_SEQUENCE);
			destroy_regex_parser_node_tree(state, n);
			return (struct regex_parser_node *)0;
		}
	}else{
		return (struct regex_parser_node *)0;
	}
}

static struct regex_parser_node * postfix_operator(struct regex_compiler_state * state){
	struct regex_parser_node * n = (struct regex_parser_node *)0;
	if(state->errors){ return n; }
	if((n = regex_accept(state, '+'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_POSTFIX_OPERATOR);
	}else if((n = regex_accept(state, '?'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_POSTFIX_OPERATOR);
	}else if((n = regex_accept(state, '*'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_POSTFIX_OPERATOR);
	}else{
		return (struct regex_parser_node *)0;
	}
}

static struct regex_parser_node * infix_expression_rest(struct regex_compiler_state * state){
	struct regex_parser_node * n = (struct regex_parser_node *)0;
	if(state->errors){ return n; }
	if((n = regex_accept(state, '|'))){
		if((n->next = regular_expression(state))){
			if((n->next->next = infix_expression_rest(state))){
				return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_INFIX_EXPRESSION_REST);
			}else{
				set_error_state(state, REGEX_ERROR_EXPECTED_INFIX_EXPRESSION_REST);
				destroy_regex_parser_node_tree(state, n);
				return (struct regex_parser_node *)0;
			}
		}else{
			set_error_state(state, REGEX_ERROR_INVALID_REGULAR_EXPRESSION);
			destroy_regex_parser_node_tree(state, n);
			return (struct regex_parser_node *)0;
		}
	}else if((n = regex_accept(state, ')'))){
		return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_INFIX_EXPRESSION_REST);
	}else{
		return (struct regex_parser_node *)0;
	}
}

static struct regex_parser_node * infix_expression(struct regex_compiler_state * state){
	struct regex_parser_node * n = (struct regex_parser_node *)0;
	if(state->errors){ return n; }
	if((n = regex_accept(state, '('))){
		if((n->next = regular_expression(state))){
			if((n->next->next = infix_expression_rest(state))){
				return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_INFIX_EXPRESSION);
			}else{
				set_error_state(state, REGEX_ERROR_EXPECTED_INFIX_EXPRESSION_REST);
				destroy_regex_parser_node_tree(state, n);
				return (struct regex_parser_node *)0;
			}
		}else{
			set_error_state(state, REGEX_ERROR_INVALID_REGULAR_EXPRESSION);
			destroy_regex_parser_node_tree(state, n);
			return (struct regex_parser_node *)0;
		}
	}else{
		return (struct regex_parser_node *)0;
	}
}

static struct regex_parser_node * regex_postfix_expression(struct regex_compiler_state * state){
	struct regex_parser_node * n = (struct regex_parser_node *)0;
	if(state->errors){ return n; }
	if((n = character_sequence(state))){
		if((n->next = postfix_operator(state))){
			return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_POSTFIX_EXPRESSION);
		}else{
			return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_POSTFIX_EXPRESSION);
		}
	}else if((n = infix_expression(state))){
		if((n->next = postfix_operator(state))){
			return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_POSTFIX_EXPRESSION);
		}else{
			return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_POSTFIX_EXPRESSION);
		}
	}else{
		return (struct regex_parser_node *)0;
	}
}

static struct regex_parser_node * regular_expression(struct regex_compiler_state * state){
	struct regex_parser_node * n = (struct regex_parser_node *)0;
	if(state->errors){ return n; }
	if((n = regex_postfix_expression(state))){
		if((n->next = regular_expression(state))){
			return create_regex_parser_node(state, (struct regex_parser_node *)0, n, 0, REGEX_REGULAR_EXPRESSION);
		}else{
			set_error_state(state, REGEX_ERROR_INVALID_REGULAR_EXPRESSION);
			destroy_regex_parser_node_tree(state, n);
			return (struct regex_parser_node *)0;
		}
	}else{
		if(state->errors){ return n; }
		return create_regex_parser_node(state, (struct regex_parser_node *)0, regex_make_epsilon(state), 0, REGEX_REGULAR_EXPRESSION);
	}
}

static void regex_compiler_state_parse(struct regex_compiler_state * state){
	if((state->top_node = regular_expression(state))){
		/*  Should have consumed all characters. */
		if(state->position != state->buffer_length){
			set_error_state(state, REGEX_ERROR_INCOMPLETE_PARSING);
		}
	}else{
		set_error_state(state, REGEX_ERROR_PARSING_FAILED);
	}
}

static struct regex_parser_node * reg_first_child(struct regex_parser_node * p){
	return p->first_child;
}

static struct regex_parser_node * reg_second_child(struct regex_parser_node * p){
	return p->first_child->next;
}

static struct regex_parser_node * reg_third_child(struct regex_parser_node * p){
	return p->first_child->next->next;
}

static struct regex_parser_node * reg_fourth_child(struct regex_parser_node * p){
	return p->first_child->next->next->next;
}

static struct regex_parser_node * reg_is_first_child_type(struct regex_parser_node * p, enum regex_parser_node_type t){
	return (
		reg_first_child(p) &&
		reg_first_child(p)->type == t
	) ? reg_first_child(p) : (struct regex_parser_node *)0;
}

static struct regex_parser_node * reg_is_second_child_type(struct regex_parser_node * p, enum regex_parser_node_type t){
	return (
		reg_first_child(p) &&
		reg_second_child(p) &&
		reg_second_child(p)->type == t
	) ? reg_second_child(p) : (struct regex_parser_node *)0;
}

static struct regex_parser_node * reg_is_third_child_type(struct regex_parser_node * p, enum regex_parser_node_type t){
	return (
		reg_first_child(p) &&
		reg_second_child(p) &&
		reg_third_child(p) &&
		reg_third_child(p)->type == t
	) ? reg_third_child(p) : (struct regex_parser_node *)0;
}

static struct regex_parser_node * reg_is_fourth_child_type(struct regex_parser_node * p, enum regex_parser_node_type t){
	return (
		reg_first_child(p) &&
		reg_second_child(p) &&
		reg_third_child(p) &&
		reg_fourth_child(p) &&
		reg_fourth_child(p)->type == t
	) ? reg_fourth_child(p) : (struct regex_parser_node *)0;
}

static int reg_check_one_child(struct regex_parser_node * p, enum regex_parser_node_type t1){
	return (reg_is_first_child_type(p, t1) && 1);
}

static int reg_check_two_children(struct regex_parser_node * p, enum regex_parser_node_type t1, enum regex_parser_node_type t2){
	return (
		reg_is_first_child_type(p, t1) &&
		reg_is_second_child_type(p, t2)
	);
}

static int reg_check_three_children(struct regex_parser_node * p, enum regex_parser_node_type t1, enum regex_parser_node_type t2, enum regex_parser_node_type t3){
	return (
		reg_is_first_child_type(p, t1) &&
		reg_is_second_child_type(p, t2) &&
		reg_is_third_child_type(p, t3)
	);
}

static int reg_check_four_children(struct regex_parser_node * p, enum regex_parser_node_type t1, enum regex_parser_node_type t2, enum regex_parser_node_type t3, enum regex_parser_node_type t4){
	return (
		reg_is_first_child_type(p, t1) &&
		reg_is_second_child_type(p, t2) &&
		reg_is_third_child_type(p, t3) &&
		reg_is_fourth_child_type(p, t4)
	);
}

static unsigned char process_hex_digit(struct regex_parser_node * p){
	unsigned char c;
	assert(p->type == REGEX_HEX_DIGIT);
	c = p->first_child->c;
	if(c >= '0' && c <= '9'){
		return c - '0';
	}else if(c >= 'a' && c <= 'f'){
		return (c - 'a') + 10;
	}else if(c >= 'A' && c <= 'F'){
		return (c - 'A') + 10;
	}else{
		assert(0 && "Internal error: Should not happen.");
		return 0;
	}
}

static unsigned char process_non_class_character(struct regex_parser_node * p){
	assert(p->type = REGEX_NON_CLASS_CHARACTER);
	p = p->first_child;
	if(p->type == REGEX_ESCAPED_CHARACTER){
		unsigned char c = p->first_child->next->first_child->c;
		switch(c){
			case 'n':{
				return '\n';
			}case 't':{
				return '\t';
			}case '(':{
				return '(';
			}case ')':{
				return ')';
			}case '[':{
				return '[';
			}case ']':{
				return ']';
			}case '*':{
				return '*';
			}case '.':{
				return '.';
			}case '-':{
				return '-';
			}case '|':{
				return '|';
			}case '+':{
				return '+';
			}case '?':{
				return '?';
			}case '^':{
				return '^';
			}case '\\':{
				return '\\';
			}case 'x':{
				struct regex_parser_node * first_digit = p->first_child->next->first_child->next;
				return (process_hex_digit(first_digit) * 16) + process_hex_digit(first_digit->next);
			}default:{
				printf("Character was '%c'.\n", c);
				assert(0 && "Internal error: Unknown escaped character.");
			}
		}
	}else if(p->type == REGEX_TERMINAL){ /*  Any other character */
		return p->c;
	}else{
		assert(0 && "Should not happen.");
		return 0;
	}
}

static struct regex_computation_node * create_new_regex_computation_node(struct regex_compiler_state * state){
	struct regex_computation_node * n = struct_regex_computation_node_memory_pool_malloc(state->m);
	n->path1 = (struct regex_computation_node *)0;
	n->path2 = (struct regex_computation_node *)0;
	n->after = (struct regex_computation_node *)0;
	n->ranges = (struct character_class_range *)0;
	n->type = REGEX_COMP_UNUSED;
	n->c = 0;
	return n;
}

static struct regex_computation_node * get_last_node(struct regex_computation_node * p){
	assert(p);
	while(p->after){
		p = p->after;
	}
	return p;
}

static struct character_class_range * make_character_range(struct regex_parser_node * p){
	struct character_class_range * r = (struct character_class_range *)malloc(sizeof(struct character_class_range));
	r->next = (struct character_class_range *)0;
	assert(p->type == REGEX_CHARACTER_OR_RANGE);
	p = p->first_child;
	if(p->type == REGEX_CHARACTER_RANGE){
		r->low = process_non_class_character(p->first_child);
		r->high = process_non_class_character(p->first_child->next->next);
		r->is_dot = 0;
	}else if(p->type == REGEX_NON_CLASS_CHARACTER){
		r->low = process_non_class_character(p);
		r->high = process_non_class_character(p);
		r->is_dot = 0;
	}else if(p->type == REGEX_TERMINAL){/*  This is for a '.' control character. */
		r->is_dot = 1;
	}else{
		assert(0 && "If shouldn't happen.");
	}
	return r;
}

static struct regex_computation_node * make_character_class_node(struct regex_compiler_state * state, struct regex_parser_node * p1, struct regex_parser_node * p2, unsigned int negative){
	/*  This function is responsible for creating a linked list of all the possible options that can be checked against inside a character
	 ie. a [...]  pattern. */
	struct regex_computation_node * new_node = create_new_regex_computation_node(state);
	struct character_class_range * current;
	assert(p1->type == REGEX_CHARACTER_OR_RANGE);
	assert(p2->type == REGEX_CHARACTER_CLASS_REST);
	new_node->type = negative ? REGEX_COMP_NEG_CLASS : REGEX_COMP_CLASS;
	new_node->ranges = make_character_range(p1);
	current = new_node->ranges; /*  Remember where to link the rest of the ranges from */
	while(p2->type != REGEX_TERMINAL){
		p2 = p2->first_child;
		if(p2->type == REGEX_CHARACTER_OR_RANGE){
			current->next = make_character_range(p2);
			current = current->next;
			p2 = p2->next; /*  Move to character_class_rest */
		}else{
			assert(p2->type == REGEX_TERMINAL);
		}
	}
	return new_node;
}

static struct regex_computation_node * reg_character_class(struct regex_compiler_state * state, struct regex_parser_node * p){
	if(state->errors){ return (struct regex_computation_node *)0; }
	if(reg_check_three_children(p, REGEX_TERMINAL, REGEX_CHARACTER_OR_RANGE, REGEX_CHARACTER_CLASS_REST)){
		struct regex_parser_node * n = reg_second_child(p);
		struct regex_parser_node * o = reg_third_child(p);
		return make_character_class_node(state, n, o, 0);
	}else if(reg_check_four_children(p, REGEX_TERMINAL, REGEX_TERMINAL, REGEX_CHARACTER_OR_RANGE, REGEX_CHARACTER_CLASS_REST)){
		struct regex_parser_node * n = reg_third_child(p);
		struct regex_parser_node * o = reg_fourth_child(p);
		return make_character_class_node(state, n, o, 1);
	}else{
		assert(0 && "Should not happen.");
		return (struct regex_computation_node *)0;
	}
}

static struct regex_computation_node * reg_non_class_character(struct regex_compiler_state * state, struct regex_parser_node * p){
	struct regex_computation_node * n = create_new_regex_computation_node(state);
	if(state->errors){ return (struct regex_computation_node *)0; }
	n->c = process_non_class_character(p);
	n->type = REGEX_COMP_CHAR;
	return n;
}

static struct regex_computation_node * make_dot_character(struct regex_compiler_state * state){
	struct regex_computation_node * n = create_new_regex_computation_node(state);
	if(state->errors){ return (struct regex_computation_node *)0; }
	n->type = REGEX_COMP_DOT;
	return n;
}

static struct regex_computation_node * reg_character_or_class(struct regex_compiler_state * state, struct regex_parser_node * p){
	if(state->errors){ return (struct regex_computation_node *)0; }
	if(reg_check_one_child(p, REGEX_CHARACTER_CLASS)){
		return reg_character_class(state, reg_first_child(p));
	}else if(reg_check_one_child(p, REGEX_NON_CLASS_CHARACTER)){
		return reg_non_class_character(state, reg_first_child(p));
	}else if(reg_check_one_child(p, REGEX_TERMINAL)){
		return make_dot_character(state);
	}else{
		assert(0 && "Should not happen.");
		return (struct regex_computation_node *)0;
	}
}

static struct regex_computation_node * reg_character_sequence_rest(struct regex_compiler_state * state, struct regex_parser_node * p){
	if(state->errors){ return (struct regex_computation_node *)0; }
	if(reg_check_two_children(p, REGEX_CHARACTER_OR_CLASS, REGEX_CHARACTER_SEQUENCE_REST)){
		struct regex_computation_node * n = reg_character_or_class(state, reg_first_child(p));
		if(n){
			get_last_node(n)->after = reg_character_sequence_rest(state, reg_second_child(p));
		}
		return n;
	}else if(reg_check_one_child(p, REGEX_EPSILON)){
		return (struct regex_computation_node *)0;
	}else{
		assert(0 && "Should not happen.");
		return (struct regex_computation_node *)0;
	}
}

static struct regex_computation_node * reg_character_sequence(struct regex_compiler_state * state, struct regex_parser_node * p){
	if(state->errors){ return (struct regex_computation_node *)0; }
	if(reg_check_two_children(p, REGEX_CHARACTER_OR_CLASS, REGEX_CHARACTER_SEQUENCE_REST)){
		struct regex_computation_node * n = reg_character_or_class(state, reg_first_child(p));
		if(n){
			get_last_node(n)->after = reg_character_sequence_rest(state, reg_second_child(p));
			return n;
		}else{
			struct_regex_computation_node_memory_pool_free(state->m, n);
			return (struct regex_computation_node *)0;
		}
	}else{
		assert(0 && "Should not happen.");
		return (struct regex_computation_node *)0;
	}
}

static struct regex_computation_node * apply_postfix_operator(struct regex_compiler_state * state, struct regex_computation_node * n, struct regex_parser_node * p, struct regex_computation_node * p_after){
	if(reg_check_one_child(p, REGEX_TERMINAL)){
		struct regex_computation_node * last_n = n;
		struct regex_computation_node * follow_n = n;
		struct regex_computation_node * after_n;
		struct regex_computation_node * rtn;
		switch(reg_first_child(p)->c){
			case '?':{
				/*  Split into two threads, one that jumps over the pattern, and one that requires it. */
				struct regex_computation_node * optional = create_new_regex_computation_node(state);
				optional->type = REGEX_COMP_SPLIT;
				optional->after = n;
				optional->path1 = n;
				optional->path2 = p_after;
				after_n = p_after;
				rtn = optional;
				break;
			}case '*':{
				if(n->after){
					/*  Split into two threads, one that jumps over the pattern, and one that requires it. */
					struct regex_computation_node * any = create_new_regex_computation_node(state);
					struct regex_computation_node * again = create_new_regex_computation_node(state);
					again->type = REGEX_COMP_JUMP;
					again->after = p_after;
					again->path1 = any;

					any->type = REGEX_COMP_SPLIT;
					any->after = n;
					any->path1 = n;  /*  See if we can match the pattern */
					any->path2 = p_after;  /*  Or just give up */
					after_n = again; /*  After the pattern, we can go back and match it again */
					rtn = any;
				}else{/*  Optimization to avoid unncessary splits */
					switch(n->type){
						case REGEX_COMP_CHAR:{
							n->type = REGEX_COMP_CHAR_STAR;
							break;
						}case REGEX_COMP_CLASS:{
							n->type = REGEX_COMP_CLASS_STAR;
							break;
						}case REGEX_COMP_NEG_CLASS:{
							n->type = REGEX_COMP_NEG_CLASS_STAR;
							break;
						}case REGEX_COMP_DOT:{
							n->type = REGEX_COMP_DOT_STAR;
							break;
						}default:{
							assert(0 && "Not considered.");
						}
					}
					n->after = p_after;
					n->path1 = n; /*  Just re-queue itself */
					return n;
				}
				break;
			}case '+':{
				/*  After pattern, split into two threads, one that jumps back over the pattern, and just continues. */
				struct regex_computation_node * again = create_new_regex_computation_node(state);
				again->type = REGEX_COMP_SPLIT;
				again->after = p_after;
				again->path1 = p_after;
				again->path2 = n;
				after_n = again; /*  After the pattern, we can go back and match it again */
				rtn = n;
				break;
			}default:{
				assert(0 && "Should not happen.");
				after_n = (struct regex_computation_node *)0;
				rtn = (struct regex_computation_node *)0;
			}
		}
		/*  If any special paths are null, assume they should be set to the next node */
		while(follow_n){
			switch(follow_n->type){
				case REGEX_COMP_SPLIT:{
					if(!follow_n->path1){
						follow_n->path1 = after_n;
					}
					if(!follow_n->path2){
						follow_n->path2 = after_n;
					}
					break;
				}case REGEX_COMP_JUMP:{
					if(!follow_n->path1){
						follow_n->path1 = after_n;
					}
					break;
				}default:{
				}
			}
			last_n = follow_n;
			follow_n = follow_n->after;
		}
		/*  Last node needs after set */
		last_n->after = after_n;
		return rtn;
	}else{
		assert(0 && "Should not happen.");
		return (struct regex_computation_node *)0;
	}
}

static struct regex_computation_node * reg_infix_expression_rest(struct regex_compiler_state * state, struct regex_parser_node * p, struct regex_computation_node * p_after){
	if(state->errors){ return (struct regex_computation_node *)0; }
	if(reg_check_three_children(p, REGEX_TERMINAL, REGEX_REGULAR_EXPRESSION, REGEX_INFIX_EXPRESSION_REST)){
		if(reg_first_child(p)->c == '|'){
			if(reg_first_child(reg_third_child(p))->c == ')'){/*  If this is the last option don't do a split */
				return reg_regular_expression(state, reg_second_child(p), p_after);
			}else{
				struct regex_computation_node * second_option = reg_infix_expression_rest(state, reg_third_child(p), p_after);
				struct regex_computation_node * jump = create_new_regex_computation_node(state);
				struct regex_computation_node * option = create_new_regex_computation_node(state);
				struct regex_computation_node * first_option;
				jump->type = REGEX_COMP_JUMP;
				jump->after = second_option;
				jump->path1 = p_after;

				first_option = reg_regular_expression(state, reg_second_child(p), jump);

				option->type = REGEX_COMP_SPLIT;
				option->after = first_option;
				option->path1 = first_option;
				option->path2 = second_option;
				return option;
			}
		}else{
			assert(0 && "Should not happen.");
			return (struct regex_computation_node *)0;
		}
	}else if(reg_check_one_child(p, REGEX_TERMINAL)){
		if(reg_first_child(p)->c == ')'){
			return p_after;
		}else{
			assert(0 && "Should not happen.");
			return (struct regex_computation_node *)0;
		}
	}else{
		assert(0 && "Should not happen.");
		return (struct regex_computation_node *)0;
	}
}

static struct regex_computation_node * reg_infix_expression(struct regex_compiler_state * state, struct regex_parser_node * p, struct regex_computation_node * p_after){
	if(state->errors){ return (struct regex_computation_node *)0; }
	if(reg_check_three_children(p, REGEX_TERMINAL, REGEX_REGULAR_EXPRESSION, REGEX_INFIX_EXPRESSION_REST)){
		if(reg_first_child(p)->c == '('){
			if(reg_first_child(reg_third_child(p))->c == ')'){/*  If this is the last option don't do a split */
				return reg_regular_expression(state, reg_second_child(p), p_after);
			}else{
				struct regex_computation_node * second_option = reg_infix_expression_rest(state, reg_third_child(p), p_after);
				struct regex_computation_node * jump = create_new_regex_computation_node(state);
				struct regex_computation_node * option = create_new_regex_computation_node(state);
				struct regex_computation_node * first_option;
				jump->type = REGEX_COMP_JUMP;
				jump->after = second_option;
				jump->path1 = p_after;

				first_option = reg_regular_expression(state, reg_second_child(p), jump);

				option->type = REGEX_COMP_SPLIT;
				option->after = first_option;
				option->path1 = first_option;
				option->path2 = second_option;
				return option;
			}
		}else{
			assert(0 && "Should not happen.");
			return (struct regex_computation_node *)0;
		}
	}else{
		assert(0 && "Should not happen.");
		return (struct regex_computation_node *)0;
	}
}

static struct regex_computation_node * remove_last_character(struct regex_computation_node * n){
	struct regex_computation_node * rtn = (struct regex_computation_node *)0;
	while(n->after){
		if(!n->after->after){
			rtn = n->after; /*  This was the last node */
			n->after = (struct regex_computation_node *)0;
			break;
		}
		n = n->after;
	}
	assert(rtn);
	return rtn;
}

static struct regex_computation_node * reg_postfix_expression(struct regex_compiler_state * state, struct regex_parser_node * p, struct regex_computation_node * p_after){
	if(state->errors){ return (struct regex_computation_node *)0; }

	if(reg_check_two_children(p, REGEX_CHARACTER_SEQUENCE, REGEX_POSTFIX_OPERATOR)){
		/*  This case is special because we have to take the last character our of the sequence and apply the postfix operator to it */
		struct regex_computation_node * n = reg_character_sequence(state, reg_first_child(p));
		if(state->errors){ return (struct regex_computation_node *)0; }
		if(!n){
			return p_after;
		}else if(n->after){
			/*  Take the last character off the character sequence, and apply the postfix operator to it. */
			struct regex_computation_node * postfixed = apply_postfix_operator(state, remove_last_character(n), reg_second_child(p), p_after);
			/*  Then take the second last character in the sequence, and set its after node to the postfix application */
			get_last_node(n)->after = postfixed;
			return n;
		}else{
			/*  If it is the only character, there is nothing in front */
			return apply_postfix_operator(state, n, reg_second_child(p), p_after);
		}
	}else if(reg_check_two_children(p, REGEX_INFIX_EXPRESSION, REGEX_POSTFIX_OPERATOR)){
		/*  The null 'after' node on the infix expression should get overwritten inside apply postfix operator*/
		return apply_postfix_operator(state, reg_infix_expression(state, reg_first_child(p), (struct regex_computation_node *)0), reg_second_child(p), p_after);
	}else if(reg_check_one_child(p, REGEX_CHARACTER_SEQUENCE)){
		struct regex_computation_node * n = reg_character_sequence(state, reg_first_child(p));
		get_last_node(n)->after = p_after;
		return n;
	}else if(reg_check_one_child(p, REGEX_INFIX_EXPRESSION)){
		return reg_infix_expression(state, reg_first_child(p), p_after);
	}else{
		assert(0 && "Should not happen.");
		return (struct regex_computation_node *)0;
	}
}

static struct regex_computation_node * reg_regular_expression(struct regex_compiler_state * state, struct regex_parser_node * p, struct regex_computation_node * p_after){
	if(state->errors){ return (struct regex_computation_node *)0; }

	if(reg_check_two_children(p, REGEX_POSTFIX_EXPRESSION, REGEX_REGULAR_EXPRESSION)){
		return reg_postfix_expression(state, reg_first_child(p), reg_regular_expression(state, reg_second_child(p), p_after));
	}else if(reg_check_one_child(p, REGEX_EPSILON)){
		return p_after;
	}else{
		assert(0 && "Should not happen.");
		return (struct regex_computation_node *)0;
	}
}

void regex_compiler_state_compile(struct regex_compiler_state * state){
	struct regex_computation_node * match = create_new_regex_computation_node(state);
	match->type = REGEX_COMP_MATCH;
	match->after = (struct regex_computation_node *)0;
	match->match_id = state->match_id;
	/*  Do parsing */
	regex_compiler_state_parse(state);
	/*  Do code generation */
	state->first_computation_node = reg_regular_expression(state, state->top_node, match);
	if(state->errors){
		destroy_regex_computation_nodes(state, match);
	}
}

static void explain_character_range(struct character_class_range * n){
	while(n){
		if(n->is_dot){
			printf("any non-newline");
		}else{
			if(n->low == n->high){
				printf("'%c'", n->low);
			}else{
				printf("'%c' to '%c'", n->low, n->high);
			}
		}
		n = n->next;
		if(n){
			printf(", ");
		}
	}
}

static void explain_error(struct regex_compiler_state * state){
	struct regex_compiler_error * error = state->errors;
	unsigned int i;
	printf("Begin displaying error stack\n");
	while(error){
		switch(error->type){
			case REGEX_ERROR_INVALID_CHARACTER_SEQUENCE:{
				printf("This character sequence is invalid.\n");
				break;
			}case REGEX_ERROR_NOT_ESCAPABLE:{
				printf("This back slash is trying to escape something that is not escapable.\n");
				break;
			}case REGEX_ERROR_EXPECTED_HEX_DIGIT:{
				printf("This is not a hexidecimal digit.  Expected 0-9, a-f, or A-F.\n");
				break;
			}case REGEX_ERROR_EXPECTED_INFIX_EXPRESSION_REST:{
				printf("Missing rest of infix expression.  Expected ')' or '|'.\n");
				break;
			}case REGEX_ERROR_INCOMPLETE_PARSING:{
				printf("The parser was not able to fully parse this regex because it does not match the regex grammar.\n");
				break;
			}case REGEX_ERROR_PARSING_FAILED:{
				printf("Parsing failed.\n");
				break;
			}case REGEX_ERROR_INVALID_REGULAR_EXPRESSION:{
				printf("Invalid regular expression.\n");
				break;
			}case REGEX_ERROR_INVALID_CHARACTER_RANGE:{
				printf("Invalid character range.\n");
				break;
			}case REGEX_ERROR_INVALID_CHARACTER_CLASS:{
				printf("Invalid character class.\n");
				break;
			}default:{
				assert(0);
			}
		}
		printf("Pattern: %s\n", state->buffer);
		printf("         ");
		for(i = 0; i < state->buffer_length; i++){
			if(i == error->character_index_of_error){
				printf("^");
			}else{
				printf(" ");
			}
		}
		printf("\n");
		error = error->next;
	}
	printf("Finished displaying error stack\n");
}

void regex_compiler_state_explain(struct regex_compiler_state * state){
	struct regex_computation_node * current_node = state->first_computation_node;
	if(state->errors){
		explain_error(state);
		return;
	}
	printf("Explaining regex...\n");
	while(current_node){
		switch(current_node->type){
			case REGEX_COMP_CHAR:{
				printf("%p: REGEX_COMP_CHAR: %c after is %p\n", (void*)current_node, current_node->c, (void*)current_node->after);
				break;
			}case REGEX_COMP_CHAR_STAR:{
				printf("%p: REGEX_COMP_CHAR_STAR: %c after is %p\n", (void*)current_node, current_node->c, (void*)current_node->after);
				break;
			}case REGEX_COMP_DOT:{
				printf("%p: REGEX_COMP_DOT after is %p\n", (void*)current_node, (void*)current_node->after);
				break;
			}case REGEX_COMP_DOT_STAR:{
				printf("%p: REGEX_COMP_DOT_STAR after is %p\n", (void*)current_node, (void*)current_node->after);
				break;
			}case REGEX_COMP_SPLIT:{
				printf("%p: REGEX_COMP_SPLIT %p %p after is %p\n", (void*)current_node, (void*)current_node->path1, (void*)current_node->path2, (void*)current_node->after);
				break;
			}case REGEX_COMP_JUMP:{
				printf("%p: REGEX_COMP_JUMP to %p after is %p\n", (void*)current_node, (void*)current_node->path1, (void*)current_node->after);
				break;
			}case REGEX_COMP_MATCH:{
				printf("%p: REGEX_COMP_MATCH after is %p\n", (void*)current_node, (void*)current_node->after);
				break;
			}case REGEX_COMP_NEG_CLASS:{
				printf("%p: REGEX_COMP_NEG_CLASS: Not one of [", (void*)current_node);
				explain_character_range(current_node->ranges);
				printf("] after is %p\n", (void*)current_node->after);
				break;
			}case REGEX_COMP_NEG_CLASS_STAR:{
				printf("%p: REGEX_COMP_NEG_CLASS_STAR: Not one of [", (void*)current_node);
				explain_character_range(current_node->ranges);
				printf("] after is %p\n", (void*)current_node->after);
				break;
			}case REGEX_COMP_CLASS:{
				printf("%p: REGEX_COMP_CLASS: One of [", (void*)current_node);
				explain_character_range(current_node->ranges);
				printf("] after is %p\n", (void*)current_node->after);
				break;
			}case REGEX_COMP_CLASS_STAR:{
				printf("%p: REGEX_COMP_CLASS_STAR: One of [", (void*)current_node);
				explain_character_range(current_node->ranges);
				printf("] after is %p\n", (void*)current_node->after);
				break;
			}default:{
				printf("Unknown node type\n");
				assert(0);
			}
		}
		current_node = current_node->after;
	}
}

static void destroy_errors(struct regex_compiler_error * n){
	if(n){
		struct regex_compiler_error * a = n->next;
		free((void*)n);
		destroy_errors(a);
	}
}

static void destroy_character_class_ranges(struct character_class_range * n){
	if(n){
		struct character_class_range * a = n->next;
		free((void*)n);
		destroy_character_class_ranges(a);
	}
}

static void destroy_regex_computation_nodes(struct regex_compiler_state * state, struct regex_computation_node * n){
	(void)state;
	if(n){
		struct regex_computation_node * a = n->after;
		destroy_character_class_ranges(n->ranges);
		struct_regex_computation_node_memory_pool_free(state->m, n);
		destroy_regex_computation_nodes(state, a);
	}
}

void regex_matcher_state_create(struct regex_matcher_state * matcher, struct regex_compiler_state ** compiler_states, unsigned int num_compiler_states){
	unsigned int i;
	struct regex_computation_node * j;
	unsigned int max_num_computation_nodes = 0;
	matcher->num_compiled_regexes = 0;
	matcher->num_unique_matches_found = 0;
	matcher->possible_matches = (struct regex_match*)malloc(sizeof(struct regex_match) * num_compiler_states); /*  In the worst case everything matches */
	matcher->actual_matches = (struct regex_match**)malloc(sizeof(struct regex_match*) * num_compiler_states); /*  In the worst case everything matches */
	matcher->compiler_states = compiler_states;
	matcher->num_compiled_regexes = num_compiler_states;

	/*  The worst-case number of states to keep track of is the number of computation nodes */
	for(i = 0; i < num_compiler_states; i++){
		assert(compiler_states[i]->match_id < num_compiler_states);
		assert(!compiler_states[i]->errors);
		assert(compiler_states[i]->first_computation_node);
		j = compiler_states[i]->first_computation_node;
		while(j){
			j->node_id = max_num_computation_nodes; /*  Set an index (unique to this matcher) that gives an index into the occupied list */
			max_num_computation_nodes++;
			j = j->after;
		}
	}
	matcher->next_list = (struct regex_computation_node **)malloc(sizeof(struct regex_computation_node *) * max_num_computation_nodes);
	matcher->current_list = (struct regex_computation_node **)malloc(sizeof(struct regex_computation_node *) * max_num_computation_nodes);
	matcher->next_occupied_list = (unsigned int *)malloc(sizeof(unsigned int) * max_num_computation_nodes);
	matcher->current_occupied_list = (unsigned int *)malloc(sizeof(unsigned int) * max_num_computation_nodes);
	/*  Initially, they are not in the list */
	for(i = 0; i < max_num_computation_nodes; i++){
		matcher->current_occupied_list[i] = 0;
		matcher->next_occupied_list[i] = 0;
	}

	matcher->num_optimized_possible_matches = (unsigned int*)malloc(sizeof(unsigned int) * 256);
	matcher->optimized_match_ids = (unsigned int**)malloc(sizeof(unsigned int*) * 256);

	matcher->num_unique_matches_found = 0;
	matcher->next_current_list_index = 0;
	matcher->next_next_list_index = 0;
	for(i = 0; i < matcher->num_compiled_regexes; i++){
		matcher->possible_matches[i].first_match = 1;  /*  Reset whether each match has been matched yet */
	}

	for(i = 0; i < 256; i++){
		regex_matcher_state_optimize(matcher, (unsigned char)i);
	}
}

void regex_matcher_state_destroy(struct regex_matcher_state * matcher){
	unsigned int i;
	free((void*)matcher->actual_matches);
	free((void*)matcher->possible_matches);
	free((void*)matcher->next_list);
	free((void*)matcher->current_list);
	free((void*)matcher->current_occupied_list);
	free((void*)matcher->next_occupied_list);
	free((void*)matcher->num_optimized_possible_matches);
	for(i = 0; i < 256; i++){
		free((void*)matcher->optimized_match_ids[i]);
	}
	free((void*)matcher->optimized_match_ids);
}

void regex_matcher_state_add(struct regex_matcher_state *, struct regex_computation_node *);

void regex_matcher_state_add(struct regex_matcher_state * matcher, struct regex_computation_node * n){
	if(!matcher->current_occupied_list[n->node_id]){
		matcher->current_occupied_list[n->node_id] = 1; /*  It is now in the list */
		matcher->current_list[matcher->next_current_list_index++] = n;
	}
}

void regex_matcher_state_add_next(struct regex_matcher_state *, struct regex_computation_node *);

void regex_matcher_state_add_next(struct regex_matcher_state * matcher, struct regex_computation_node * n){
	if(!matcher->next_occupied_list[n->node_id]){
		matcher->next_occupied_list[n->node_id] = 1; /*  It is now in the list */
		matcher->next_list[matcher->next_next_list_index++] = n;
	}
}

static void regex_matcher_state_optimize(struct regex_matcher_state * matcher, unsigned char c){
	unsigned int more_chars = 1;
	unsigned int i = 0;
	struct regex_computation_node * current;

	/*  Add every possible state, and see what matches remain after this first character  */
	matcher->num_unique_matches_found = 0;
	matcher->next_current_list_index = 0;
	matcher->next_next_list_index = 0;
	for(i = 0; i < matcher->num_compiled_regexes; i++){
		matcher->current_list[matcher->next_current_list_index] = matcher->compiler_states[i]->first_computation_node;
		matcher->next_current_list_index++;

		matcher->possible_matches[i].first_match = 1;  /*  Reset whether each match has been matched yet */
	}

	while(matcher->next_current_list_index){ /* While there are entires in the list for the current character */
		current = matcher->current_list[--matcher->next_current_list_index];
		matcher->current_occupied_list[current->node_id] = 0; /*  No longer in the list */
		switch(current->type){
			case REGEX_COMP_CHAR:{
				if(more_chars){
					if(c == current->c){
						regex_matcher_state_add_next(matcher, current->after);
					}
				}
				break;
			}case REGEX_COMP_CHAR_STAR:{
				if(more_chars){
					if(c == current->c){
						regex_matcher_state_add_next(matcher, current->path1);
					}else{
						regex_matcher_state_add(matcher, current->after);
					}
				}else{
					regex_matcher_state_add(matcher, current->after);
				}
				break;
			}case REGEX_COMP_DOT:{
				if(more_chars){
					if(c != '\n'){
						regex_matcher_state_add_next(matcher, current->after);
					}
				}
				break;
			}case REGEX_COMP_DOT_STAR:{
				if(more_chars){
					if(c != '\n'){
						regex_matcher_state_add_next(matcher, current->path1);
					}else{
						regex_matcher_state_add(matcher, current->after);
					}
				}else{
					regex_matcher_state_add(matcher, current->after);
				}
				break;
			}case REGEX_COMP_SPLIT:{
				regex_matcher_state_add(matcher, current->path1);
				regex_matcher_state_add(matcher, current->path2);
				break;
			}case REGEX_COMP_JUMP:{
				regex_matcher_state_add(matcher, current->path1);
				break;
			}case REGEX_COMP_MATCH:{
				matcher->possible_matches[current->match_id].match_node = current;
				if(matcher->possible_matches[current->match_id].first_match){ /*  Is this the first time this regex has matched? */
					matcher->actual_matches[matcher->num_unique_matches_found] = &matcher->possible_matches[current->match_id];
					matcher->num_unique_matches_found++;
					matcher->possible_matches[current->match_id].first_match = 0;
				}
				break;
			}case REGEX_COMP_NEG_CLASS:{
				if(more_chars){
					struct character_class_range * r = current->ranges;
					unsigned int matches = 0; /* Assume it does not match */
					while(r){
						if(r->is_dot){
							if(c != '\n'){
								matches = 1;
								break;
							}
						}else if(c >= r->low && c <= r->high){
							matches = 1;
							break;
						}
						r = r->next;
					}
					if(!matches){
						regex_matcher_state_add_next(matcher, current->after);
					}
				}
				break;
			}case REGEX_COMP_NEG_CLASS_STAR:{
				if(more_chars){
					struct character_class_range * r = current->ranges;
					unsigned int matches = 0; /* Assume it does not match */
					while(r){
						if(r->is_dot){
							if(c != '\n'){
								matches = 1;
								break;
							}
						}else if(c >= r->low && c <= r->high){
							matches = 1;
							break;
						}
						r = r->next;
					}
					if(matches){
						regex_matcher_state_add(matcher, current->after);
					}else{
						regex_matcher_state_add_next(matcher, current->path1);
					}
				}else{
					regex_matcher_state_add(matcher, current->after);
				}
				break;
			}case REGEX_COMP_CLASS:{
				if(more_chars){
					struct character_class_range * r = current->ranges;
					while(r){
						if(r->is_dot){
							if(c != '\n'){
								regex_matcher_state_add_next(matcher, current->after);
								break;
							}
						}else if(c >= r->low && c <= r->high){
							regex_matcher_state_add_next(matcher, current->after);
							break;
						}
						r = r->next;
					}
				}
				break;
			}case REGEX_COMP_CLASS_STAR:{
				if(more_chars){
					struct character_class_range * r = current->ranges;
					unsigned int matches = 0; /* Assume it does not match */
					while(r){
						if(r->is_dot){
							if(c != '\n'){
								matches = 1;
								break;
							}
						}else if(c >= r->low && c <= r->high){
							matches = 1;
							break;
						}
						r = r->next;
					}
					if(matches){
						regex_matcher_state_add_next(matcher, current->path1);
					}else{
						regex_matcher_state_add(matcher, current->after);
					}
				}else{
					regex_matcher_state_add(matcher, current->after);
				}
				break;
			}default:{
				printf("Unknown node type\n");
				assert(0);
			}
		}
	}
	/*  Take everything out of the next list and see what could have matched */
	while(matcher->next_next_list_index){
		matcher->next_next_list_index--;
		matcher->next_occupied_list[matcher->next_list[matcher->next_next_list_index]->node_id] = 0; /*  No longer in the list */
		current = matcher->next_list[matcher->next_next_list_index];
		current = get_last_node(current); /*  Go to end match node. */
		switch(current->type){
			case REGEX_COMP_MATCH:{
				/*  Record the match */
				matcher->possible_matches[current->match_id].match_node = current;
				if(matcher->possible_matches[current->match_id].first_match){ /*  Is this the first time this regex has matched? */
					matcher->actual_matches[matcher->num_unique_matches_found] = &matcher->possible_matches[current->match_id];
					matcher->num_unique_matches_found++;
					matcher->possible_matches[current->match_id].first_match = 0;
				}
				break;
			}default:{
				printf("Should not happen.\n");
				assert(0);
			}
		}
	}
	matcher->num_optimized_possible_matches[c] = matcher->num_unique_matches_found;

	if(matcher->num_unique_matches_found){
		/*  Make a new array to store all our match ids */
		matcher->optimized_match_ids[c] = (unsigned int *)malloc(sizeof(unsigned int) * matcher->num_unique_matches_found);
		for(i = 0; i < matcher->num_unique_matches_found; i++){
			/*  Add to the list of possible match ids for this character*/
			matcher->optimized_match_ids[c][i] = matcher->actual_matches[i]->match_node->match_id;
		}
	}else{
		matcher->optimized_match_ids[c] = (unsigned int *)0;
	}
	/*  Reset for our first match */
	matcher->num_unique_matches_found = 0;
	matcher->next_current_list_index = 0;
	matcher->next_next_list_index = 0;
}

void regex_matcher_state_run(struct regex_matcher_state * matcher, unsigned char * str, unsigned int max_length){
	unsigned int more_chars = 1;
	unsigned int j;
	unsigned int i = 0;
	unsigned int temp_next;
	struct regex_computation_node * current;
	struct regex_computation_node ** temp;
	unsigned int * temp_i;
	unsigned char first_char = max_length ? str[0] : (unsigned char)0; /*  There is an edge case where we're matching an emptry pattern against an empty string. */

        /*  Reset our state so that we can run the same compiled regex again against a different string */
        matcher->num_unique_matches_found = 0;
        matcher->next_current_list_index = 0;
        matcher->next_next_list_index = 0;

	for(j = 0; j < matcher->num_optimized_possible_matches[first_char]; j++){
		matcher->current_list[matcher->next_current_list_index] = matcher->compiler_states[matcher->optimized_match_ids[first_char][j]]->first_computation_node;
		matcher->next_current_list_index++;
		matcher->possible_matches[matcher->optimized_match_ids[first_char][j]].first_match = 1;  /*  Only need to reset whether each match has been matched yet for the possible matches */
	}

	while(matcher->next_current_list_index){ /* While there are still characters to look at (after list swap) */
		while(matcher->next_current_list_index){ /* While there are entires in the list for the current character */
			current = matcher->current_list[--matcher->next_current_list_index];
			matcher->current_occupied_list[current->node_id] = 0; /*  No longer in the list */
			switch(current->type){
				case REGEX_COMP_CHAR:{
					if(more_chars){
						if(str[i] == current->c){
							regex_matcher_state_add_next(matcher, current->after);
						}
					}
					break;
				}case REGEX_COMP_CHAR_STAR:{
					if(more_chars){
						if(str[i] == current->c){
							regex_matcher_state_add_next(matcher, current->path1);
						}else{
							regex_matcher_state_add(matcher, current->after);
						}
					}else{
						regex_matcher_state_add(matcher, current->after);
					}
					break;
				}case REGEX_COMP_DOT:{
					if(more_chars){
						if(str[i] != '\n'){
							regex_matcher_state_add_next(matcher, current->after);
						}
					}
					break;
				}case REGEX_COMP_DOT_STAR:{
					if(more_chars){
						if(str[i] != '\n'){
							regex_matcher_state_add_next(matcher, current->path1);
						}else{
							regex_matcher_state_add(matcher, current->after);
						}
					}else{
						regex_matcher_state_add(matcher, current->after);
					}
					break;
				}case REGEX_COMP_SPLIT:{
					regex_matcher_state_add(matcher, current->path1);
					regex_matcher_state_add(matcher, current->path2);
					break;
				}case REGEX_COMP_JUMP:{
					regex_matcher_state_add(matcher, current->path1);
					break;
				}case REGEX_COMP_MATCH:{
					matcher->possible_matches[current->match_id].match_node = current;
					matcher->possible_matches[current->match_id].length = i;
					if(matcher->possible_matches[current->match_id].first_match){ /*  Is this the first time this regex has matched? */
						matcher->actual_matches[matcher->num_unique_matches_found] = &matcher->possible_matches[current->match_id];
						matcher->num_unique_matches_found++;
						matcher->possible_matches[current->match_id].first_match = 0;
					}
					break;
				}case REGEX_COMP_NEG_CLASS:{
					if(more_chars){
						struct character_class_range * r = current->ranges;
						unsigned int matches = 0; /* Assume it does not match */
						while(r){
							if(r->is_dot){
								if(str[i] != '\n'){
									matches = 1;
									break;
								}
							}else if(str[i] >= r->low && str[i] <= r->high){
								matches = 1;
								break;
							}
							r = r->next;
						}
						if(!matches){
							regex_matcher_state_add_next(matcher, current->after);
						}
					}
					break;
				}case REGEX_COMP_NEG_CLASS_STAR:{
					if(more_chars){
						struct character_class_range * r = current->ranges;
						unsigned int matches = 0; /* Assume it does not match */
						while(r){
							if(r->is_dot){
								if(str[i] != '\n'){
									matches = 1;
									break;
								}
							}else if(str[i] >= r->low && str[i] <= r->high){
								matches = 1;
								break;
							}
							r = r->next;
						}
						if(matches){
							regex_matcher_state_add(matcher, current->after);
						}else{
							regex_matcher_state_add_next(matcher, current->path1);
						}
					}else{
						regex_matcher_state_add(matcher, current->after);
					}
					break;
				}case REGEX_COMP_CLASS:{
					if(more_chars){
						struct character_class_range * r = current->ranges;
						while(r){
							if(r->is_dot){
								if(str[i] != '\n'){
									regex_matcher_state_add_next(matcher, current->after);
									break;
								}
							}else if(str[i] >= r->low && str[i] <= r->high){
								regex_matcher_state_add_next(matcher, current->after);
								break;
							}
							r = r->next;
						}
					}
					break;
				}case REGEX_COMP_CLASS_STAR:{
					if(more_chars){
						struct character_class_range * r = current->ranges;
						unsigned int matches = 0; /* Assume it does not match */
						while(r){
							if(r->is_dot){
								if(str[i] != '\n'){
									matches = 1;
									break;
								}
							}else if(str[i] >= r->low && str[i] <= r->high){
								matches = 1;
								break;
							}
							r = r->next;
						}
						if(matches){
							regex_matcher_state_add_next(matcher, current->path1);
						}else{
							regex_matcher_state_add(matcher, current->after);
						}
					}else{
						regex_matcher_state_add(matcher, current->after);
					}
					break;
				}default:{
					printf("Unknown node type\n");
					assert(0);
				}
			}
		}
		/*  Swap the occupied lists*/
		temp_i = matcher->current_occupied_list;
		matcher->current_occupied_list = matcher->next_occupied_list;
		matcher->next_occupied_list = temp_i;

		/*  Swap the next and current node lists*/
		temp = matcher->current_list;
		matcher->current_list = matcher->next_list;
		matcher->next_list = temp;

		/*  Swap the indicies of the next nodes in lists */
		temp_next = matcher->next_current_list_index;
		matcher->next_current_list_index = matcher->next_next_list_index;
		matcher->next_next_list_index = temp_next;
		more_chars = (++i) < max_length;
	}
	assert(!matcher->next_next_list_index);  /*  Make sure there are no nodes sitting in the next step (otherwise we would need to remove them). */
}


text:
package com.technosophos.rhizome.web;

/**
 * Basic constants that the {@link BaseRhizomeServlet} servlet needs.
 * This is meant to be generic enough to be portable to another app.
 * @author mbutcher
 *
 */
public class ServletConstants {
	/** The default request to be invoked if no request is specified ("default")*/
	public static final String DEFAULT_REQUEST = "default";

	/**
	  * The param in Get/Post/Cookie that contains the request ("r")
	  * This should be used in Get/Post method as the param that specifies the name of
	  * the request.
	  */
	 public static final String GPC_PARAM_REQUEST = "r";
	 /* The default request to be invoked if no request is specified ("default")*/
	 //public static final String DEFAULT_REQUEST = "default";
	 /**
	  * The name used to store the request object in the params for the request process
	  * ("_request").
	  */
	 public static final String REQ_PARAM_REQUEST_OBJ = "_request";

	 /**
	  * The BaseRhizomeSession object.
	  * @see com.technosophos.lantern.servlet.LanternSession.
	  */
	 public static final String REQ_PARAM_SESSION = "_session";

	 /**
	  * The parameter with the name of the repository.
	  * "repository"
	  */
	 public static final String REQ_PARAM_REPO = "repository";

	 /**
	  * The param name to retrieve webapp path from the params. (base_path)
	  * The {@link LanternServlet} servlet inserts the base path information
	  * (the location of the servlet's webapp directory).
	  * This is NOT the path to the repository. It is the a path to configuration
	  * information for the servlet.
	  */
	 public static final String BASE_PATH = "base_path";

	 /**
	  * The param name to retrieve the configuration dir from the params. (config_path)
	  * Set by {@link LanternServlet}. Retrieving the value from the context should
	  * provide you with the path to the configuration files, like command.xml and web.xml.
	  */
	 public static final String CONFIG_PATH = "config_path";

	 /**
	  * The param name to retrieve path information for static resources.
	  * (resource_path) Static resources are files that will be served up unaltered
	  * by the servlet engine (perhaps not even managed by the servlet). These include
	  * images, CSS, and other such files.
	  */
	 public static final String RESOURCE_PATH = "resource_path";

	 /**
	  * The base URL for this servlet.
	  * This is the path to the servlet currently being used.
	  */
	 public static final String APP_URL = "app_url";

	 /**
	  * The absolute URI.
	  *
The full path from the server root to the servlet. E.g. if the URL is
	  * http://example.com/servlet/servlet, the absolute path is /servlet/servlet.

	  */
	 public static final String ABSOLUTE_URI = "absolute_uri";

	 /**
	  * The resource URI.
	  *
The full path from the server root the location of supporting files, such as
	  * js, images, and so on.
	  * E.g. if the URL is
	  * http://example.com/servlet/js/, the absolute path is /servlet/js.

	  */
	 public static final String RESOURCE_URI = "resource_uri";

	 /**
	  * Servlet init parameter to get for FS repository path: fs_repo_path.
	  * @see com.technosophos.rhizome.repository.fs.FileSystemRepository
	  */
	 public static final String SERVPARAM_FS_REPO_PATH = "fs_repo_path";
	 /**
	  * Serlvet init parameter to get for FS index path: index_path
	  * @see com.technosophos.rhizome.repository.lucene.LuceneElements
	  */
	 public static final String SERVPARAM_INDEX_PATH = "index_path";

	 //public static final String CXT_REPO_PATH = "";

	 /**
	  * The name of the settings repository.
	  * It is "__settings".
	  */
	 public static final String SETTINGS_REPO = "__settings";
}

redpajama_set_name: RedPajamaGithub


text:
let { Cc, Ci } = require("chrome");
let prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].getService(Ci.nsIPromptService);
let prefs = require("sdk/simple-prefs");
let Util = require("lib/util");

/**
 * Preference manager
 * @constructor
 */
const Prefs = function(){
    this.frame = null;
    this.frame_url = "";
    this.db = null;
};

/**
 * Initialize preference.
 * @param {Object} frame - Must be the result of require("sdk/ui/frame").Frame({})
 * @param {string} frame_url - Url of the frame
 * @param {Object} sidebar - Instance of require("lib/sidebar")
 * @param {Object} tooltip - Instance of require("lib/tooltip")
 * @param {Object} db - Must be the instance generated by require("lib/db").
 */
Prefs.prototype.init = function(frame, frame_url, sidebar, tooltip, db){
    if( ! (frame && frame_url && sidebar && tooltip && db) ){
        throw new Error("Insufficient parameter");
    }

    this.frame = frame;
    this.frame_url = frame_url;
    this.sidebar = sidebar;
    this.tooltip = tooltip;
    this.db = db;

    /**
     * @todo For cleaner readability, I think the code below should be moved into lib/sidebar.js.
     */
    // Send initial configuration to tooltip/sidebar
    this.sidebar.setFontSize(prefs.prefs["font_size"]);

    prefs.on("save_search_history", (pref_name) => {
        let msg = {};
        if(prefs.prefs[pref_name]){
            msg.type = "show_history_button";
        }
        else{
            msg.type = "hide_history_button";
            if (prompts.confirm(null, "確認", "現在までの検索履歴を削除しますか? (取消できません)")) { // "Confirmation", "Do you want to delete search history? (You cannot undo this operation)"
                this.db.clear();
            }
        }
        this.frame.postMessage(JSON.stringify(msg), this.frame_url);
    });

    prefs.on("show_result_with_history", () => {
        prefs.prefs["display_target"] = "sidebar";
    });

    prefs.on("panel_position", () => {
        prefs.prefs["display_target"] = "panel";
    });

    prefs.on("show_search_button_for_selection", () => {
        this.tooltip.toggleShowButtonForSelection(prefs.prefs["show_search_button_for_selection"]);
    });

    prefs.on("always_open_new_tab", () => {
        prefs.prefs["display_target"] = "tab";
    });

    prefs.on("service_name", () => {
        let msg = {
            type: "update-placeholder",
            data: prefs.prefs["service_name"] + "で検索"
        };
        this.frame.postMessage(JSON.stringify(msg), this.frame_url);
    });

    prefs.on("service_url", () => {
    });

    prefs.on("service_selector", () => {
    });

    // Modification of default setting from v0.0.1. after v0.0.1, ... > li:first will not work.
    if(prefs.prefs["service_selector"] === "#resultsList > ul > li:first"){
        prefs.prefs["service_selector"] = "#resultsList > ul > li:first-child";
    }

    prefs.on("clear_history", () => {
        if (prompts.confirm(null, "警告", "全ての履歴が削除され、元に戻せませんがよろしいですか?")) { // "Caution", "All histories will be deleted and never set back. Are you sure to delete?"
            this.db.clear();
        }
    });

    prefs.on("export_history", () => {
        Util.exportFormattedDataToFile(this.db);
    });

    prefs.on("dump_history", () => {
        Util.exportDumpToFile(this.db);
    });

    prefs.on("font_size", (pref_name) => {
        this.sidebar.setFontSize(prefs.prefs[pref_name]);
        this.tooltip.setFontSize(prefs.prefs[pref_name]);
    });
};

/**
 * Return array of preferences.
 * @returns {null|*}
 */
Prefs.prototype.getAll = function(){
    return prefs.prefs;
};

/**
 * Return preference value by its name
 * @param {string} name - Preference name
 * @returns {*}
 */
Prefs.prototype.get = function(name){
    return prefs.prefs[name];
};

/**
 * Set preference value
 * @param {string} name - pref name
 * @param {*} value - pref value
 */
Prefs.prototype.set = function(name, value){
    prefs.prefs[name] = value;
};

module.exports = Prefs;


text:
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models

class Migration(SchemaMigration):

    def forwards(self, orm):
        # Adding field 'TutorialUser.http_user_agent'
        db.add_column(u'docker_tutorial_tutorialuser', 'http_user_agent',
                      self.gf('django.db.models.fields.CharField')(default='', max_length=256, blank=True),
                      keep_default=False)

        # Adding field 'TutorialUser.http_remote_address'
        db.add_column(u'docker_tutorial_tutorialuser', 'http_remote_address',
                      self.gf('django.db.models.fields.CharField')(default='', max_length=32, blank=True),
                      keep_default=False)

        # Adding field 'TutorialUser.http_accept_language'
        db.add_column(u'docker_tutorial_tutorialuser', 'http_accept_language',
                      self.gf('django.db.models.fields.CharField')(default='', max_length=128, blank=True),
                      keep_default=False)

        # Adding field 'TutorialUser.http_accept_encoding'
        db.add_column(u'docker_tutorial_tutorialuser', 'http_accept_encoding',
                      self.gf('django.db.models.fields.CharField')(default='', max_length=128, blank=True),
                      keep_default=False)

        # Adding field 'TutorialUser.http_referrer'
        db.add_column(u'docker_tutorial_tutorialuser', 'http_referrer',
                      self.gf('django.db.models.fields.CharField')(default='', max_length=128, blank=True),
                      keep_default=False)

        # Changing field 'TutorialUser.label'
        db.alter_column(u'docker_tutorial_tutorialuser', 'label', self.gf('django.db.models.fields.CharField')(max_length=80))

    def backwards(self, orm):
        # Deleting field 'TutorialUser.http_user_agent'
        db.delete_column(u'docker_tutorial_tutorialuser', 'http_user_agent')

        # Deleting field 'TutorialUser.http_remote_address'
        db.delete_column(u'docker_tutorial_tutorialuser', 'http_remote_address')

        # Deleting field 'TutorialUser.http_accept_language'
        db.delete_column(u'docker_tutorial_tutorialuser', 'http_accept_language')

        # Deleting field 'TutorialUser.http_accept_encoding'
        db.delete_column(u'docker_tutorial_tutorialuser', 'http_accept_encoding')

        # Deleting field 'TutorialUser.http_referrer'
        db.delete_column(u'docker_tutorial_tutorialuser', 'http_referrer')

        # Changing field 'TutorialUser.label'
        db.alter_column(u'docker_tutorial_tutorialuser', 'label', self.gf('django.db.models.fields.CharField')(max_length=80, null=True))

    models = {
        u'docker_tutorial.dockerfileevent': {
            'Meta': {'object_name': 'DockerfileEvent'},
            'errors': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'item': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
            'level': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
            'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['docker_tutorial.TutorialUser']"})
        },
        u'docker_tutorial.subscriber': {
            'Meta': {'unique_together': "(('email', 'from_level'),)", 'object_name': 'Subscriber'},
            'email': ('django.db.models.fields.EmailField', [], {'max_length': '80'}),
            'from_level': ('django.db.models.fields.IntegerField', [], {}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['docker_tutorial.TutorialUser']"})
        },
        u'docker_tutorial.tutorialevent': {
            'Meta': {'object_name': 'TutorialEvent'},
            'command': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '80', 'blank': 'True'}),
            'feedback': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '2000', 'blank': 'True'}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'question': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}),
            'timestamp': ('django.db.models.fields.DateTimeField', [], {'auto_now': 'True', 'blank': 'True'}),
            'type': ('django.db.models.fields.CharField', [], {'max_length': '15'}),
            'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['docker_tutorial.TutorialUser']"})
        },
        u'docker_tutorial.tutorialuser': {
            'Meta': {'object_name': 'TutorialUser'},
            'http_accept_encoding': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}),
            'http_accept_language': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}),
            'http_referrer': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '128', 'blank': 'True'}),
            'http_remote_address': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '32', 'blank': 'True'}),
            'http_user_agent': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '256', 'blank': 'True'}),
            u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
            'label': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '80', 'blank': 'True'}),
            'session_key': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
            'timestamp': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now', 'auto_now': 'True', 'blank': 'True'})
        }
    }

    complete_apps = ['docker_tutorial']


text:
/// Copyright (c) 2012 Ecma International.  All rights reserved.
/**
 * @path ch15/15.4/15.4.4/15.4.4.15/15.4.4.15-5-28.js
 * @description Array.prototype.lastIndexOf - side effects produced by step 1 are visible when an exception occurs
 */

function testcase() {

        var stepFiveOccurs = false;
        var fromIndex = {
            valueOf: function () {
                stepFiveOccurs = true;
                return 0;
            }
        };

        try {
            Array.prototype.lastIndexOf.call(undefined, undefined, fromIndex);
            return false;
        } catch (e) {
            return (e instanceof TypeError) && !stepFiveOccurs;
        }
    }
runTestCase(testcase);


text: package 'firefox'


text:
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license.
//
// Microsoft Cognitive Services (formerly Project Oxford): https://www.microsoft.com/cognitive-services
//
// Microsoft Cognitive Services (formerly Project Oxford) GitHub:
// https://github.com/Microsoft/ProjectOxford-ClientSDK
//
// Copyright (c) Microsoft Corporation
// All rights reserved.
//
// MIT License:
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//

using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;

namespace SampleUserControlLibrary
{
    public class Scenario
    {
        public string Title
        {
            set;
            get;
        }

        public Type PageClass
        {
            get;
            set;
        }
    }

    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class SampleScenarios : UserControl
    {
        public static DependencyProperty SampleTitleProperty =
            DependencyProperty.Register("SampleTitle", typeof(string), typeof(SampleScenarios));

        public static DependencyProperty SampleScenarioListProperty =
            DependencyProperty.Register("SampleScenarioList", typeof(Scenario[]), typeof(SampleScenarios));

        private SubscriptionKeyPage _subscriptionPage;

        public string SampleTitle
        {
            get { return (string)GetValue(SampleTitleProperty); }
            set { SetValue(SampleTitleProperty, value); }
        }

        public Scenario[] SampleScenarioList
        {
            get { return (Scenario[])GetValue(SampleScenarioListProperty); }
            set
            {
                SetValue(SampleScenarioListProperty, value);
                _scenarioListBox.ItemsSource = SampleScenarioList;
            }
        }

        /// <summary>
        /// Gets or sets the disclaimer
        /// </summary>
        public string Disclaimer
        {
            get { return _disclaimerTextBlock.Text; }
            set { _disclaimerTextBlock.Text = value; }
        }

        public string SubscriptionKey
        {
            get;
            set;
        }

        public SampleScenarios()
        {
            InitializeComponent();
            _subscriptionPage = new SubscriptionKeyPage(this);
            SubscriptionKey = _subscriptionPage.SubscriptionKey;

            SampleTitle = "Replace SampleNames with SampleScenarios.SampleTitle property";

            SampleScenarioList = new Scenario[]
            {
                new Scenario { Title = "Scenario 1: Replace items using SampleScenarios.ScenarioList" },
                new Scenario { Title = "Scenario 2: Replace items using SampleScenarios.ScenarioList" }
            };

            _scenarioListBox.ItemsSource = SampleScenarioList;

            _scenarioFrame.Navigate(_subscriptionPage);
        }

        public void Log(string logMessage)
        {
            if (String.IsNullOrEmpty(logMessage) || logMessage == "\n")
            {
                _logTextBox.Text += "\n";
            }
            else
            {
                string timeStr = DateTime.Now.ToString("HH:mm:ss.ffffff");
                string messaage = "[" + timeStr + "]: " + logMessage + "\n";
                _logTextBox.Text += messaage;
            }
            _logTextBox.ScrollToEnd();
        }

        public void ClearLog()
        {
            _logTextBox.Text = "";
        }

        private void ScenarioChanged(object sender, SelectionChangedEventArgs e)
        {
            ListBox scenarioListBox = sender as ListBox;
            Scenario scenario = scenarioListBox.SelectedItem as Scenario;
            ClearLog();

            if (scenario != null)
            {
                Page page = Activator.CreateInstance(scenario.PageClass) as Page;
                page.DataContext = this.DataContext;
                _scenarioFrame.Navigate(page);
            }
        }

        private void SubscriptionManagementButton_Click(object sender, RoutedEventArgs e)
        {
            _scenarioFrame.Navigate(_subscriptionPage);
            // Reset the selection so that we can get SelectionChangedEvent later.
            _scenarioListBox.SelectedIndex = -1;
        }
    }

    public class ScenarioBindingConverter : IValueConverter
    {
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Scenario s = value as Scenario;
            if (s != null)
            {
                return s.Title;
            }
            return null;
        }

        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}


text:
njet-configuration [![Build Status](https://travis-ci.org/dariuszp/njet-configuration.png?branch=master)](https://travis-ci.org/dariuszp/njet-configuration)
==================

Configuration handler for projects.  Njet configuration is responsible for loading yaml configuration files.

## Installation

```JavaScript
npm install njet-configuration
```

## Usage

First load njet configuration

```JavaScript
var njetConfiguration = require('njet-configuration');
```

and create first configuration:

```JavaScript
var config = njetConfiguration.create();
```

## Getting data

To get Your configuration use:

```JavaScript
config.get('x'); // to get specific value
config.getConfiguration(); // to get all values as json object
```

## Set values from json objects

There are three ways to set configuration values.

```JavaScript
config.set('x', 5);
```

will set "x" to 5. Now when You get Your configuration You will receive:

```JavaScript
{ "x": 5 }
```

You can also replace whole configuration using load:

```JavaScript
config.load({
    y: 6
});
```

This will replace Your configuration and You will receive:

```JavaScript
{ "y": 6 }
```

Or You can merge two objects together:

```JavaScript
config.merge({
    z: 1
});
```

To get:

```JavaScript
{ "y": 6, "z": 1 }
```

## Merging

Merge will always do deep copy of the objects. For example:

```JavaScript
config.load({
    x: 1,
    y: ["a"]
});

config.merge({
    y: ["b"],
    z: 3
});
```

Will result:

```JavaScript
{ "x": 1, "y": ["a", "b"], "z": 3 }
```

## Validating

There are two ways to validate objects. You can add validators:

```JavaScript
config.addValidator(function (config) {
    if (config.key === undefined) {
        return false;
    }
    return true;
});
```

Or schema:

```JavaScript
config.schema({
    x: config.expect.number()
});
```

To validate configuration, simply use:

```JavaScript
config.validate();
config.isValid();
```

For more information about schema validation visit https://github.com/cruks/cruks-lib-config

## Yaml configuration files

You can load yaml files and directories containing yaml files like this:

```JavaScript
config.load('/path/to/directory');
config.load('/path/to/file.yml');
config.merge('/path/to/another_file.yml');
config.merge('/path/to/another/directory');
```

## Configuration

You cann pass options to njet configuration constructor. Like this:

```JavaScript
var config = njetConfiguration.create({
    varbosity: 1,
    expect: expect,
    loader: loader
});
```

* Verbosity above 0 (default 0) allow njet configuration to print error messages on standard output if configuration validation fails.
* expect is a module to validate configuration. It should have .schema() method that return object with .asset() method. Assert should take configuration json object as first parameter.
* loader is a module for loading data. As first argument, loader take either data object or path to file. By default loader only load .yml files.


text:
Invite others to upload to <?php $this->utility->safe($album['name']); ?>

      Your upload token is <a href="/photos/upload/<?php $this->utility->safe($token['id']); ?>"><?php $this->utility->safe($token['id']); ?>. You can email, text or instant message this URL to anyone you'd like to upload photos into this album.

    <button class="btn btn-brand copyToClipboard addSpinner" data-clipboard-text="<?php $this->utility->safe(sprintf('%s://%s/photos/upload/%s', $this->utility->getProtocol(false), $this->utility->getHost(), $this->utility->safe($token['id'], false))); ?>">Copy URL to clipboard</button>

      <?php if($token['dateExpires'] == 0) { ?>
        This URL never expires.
      <?php } else { ?>
        This URL expires in <?php echo intval(($token['dateExpires']-time())/86400); ?> days. (<?php echo $this->utility->dateLong($token['dateExpires']); ?>)
      <?php } ?>


text:
import { buildAppRoutes } from "v2/Artsy/Router/buildAppRoutes"
import { RouteConfig } from "found"
import { routes as artistRoutes } from "v2/Apps/Artist/routes"
import { routes as artworkRoutes } from "v2/Apps/Artwork/routes"
import { collectRoutes } from "v2/Apps/Collect/collectRoutes"
import { conversationRoutes } from "v2/Apps/Conversation/routes"
import { routes as identityVerificationRoutes } from "v2/Apps/IdentityVerification/routes"
import { routes as orderRoutes } from "v2/Apps/Order/routes"
import { routes as searchRoutes } from "v2/Apps/Search/routes"
import { routes as viewingRoomRoutes } from "./ViewingRoom/routes"

export function getAppRoutes(): RouteConfig[] {
  return buildAppRoutes([
    {
      routes: artistRoutes,
    },
    {
      routes: artworkRoutes,
    },
    {
      routes: collectRoutes,
    },
    {
      routes: conversationRoutes,
    },
    {
      routes: identityVerificationRoutes,
    },
    {
      routes: orderRoutes,
    },
    {
      routes: searchRoutes,
    },
    {
      routes: viewingRoomRoutes,
    },
  ])
}


text:
module Puppet::Parser::Functions
  newfunction(:add_to_scope, :doc => <<-'ENDHEREDOC') do |args|
    Expects an hash as argument. Add each key value pair to the actual scope.

    Primary used for hiera < v1.3, because hiera only with version 1.3 supports
    references to hiera values, prior to v1.3 only references to variables in
    the global puppet scope were possible. With this function, it is possible
    to load values in the global scope, if called in the manifests/site.pp:

    add_to_scope(hiera_hash('hiera::globalconfig',
      { puppettyp => 'agent', 'monitoring' => 'nrpe' }))
    ENDHEREDOC

    raise(Puppet::ParseError, "add_to_scope(): Wrong number of arguments "+
      "given (#{args.size} for 1)") if args.size != 1

    hash = args[0]
    raise(Puppet::ParseError,
      'add_to_scope(): Requires hash as argument.') unless hash.is_a?(Hash)

    hash.each do | key, val |
      debug("adding to scope #{key}: #{val}")
      self.setvar(key, val)
    end
  end
end


text:
package com.gwtjs.icustom;

import org.junit.Test;

public class UtilTest {

	@Test
	public void pathTest() {
		String uri = "";
		String fileName = "";
		int num = -1;
		boolean flag = false;

		/*uri = "/resources/images/product-1.jpg";
		num = uri.lastIndexOf(".html");flag = suffixMatcher(uri);
		fileName = uri.substring(0, uri.lastIndexOf("."));
		System.out.println(uri+"::"+flag);

		uri = "/";flag = suffixMatcher(uri);
		fileName = uri.substring(0, uri.length() - 1);
		num = uri.lastIndexOf("/");
		System.out.println(fileName.equals("/") + ":" + num);System.out.println(uri+"::"+flag);

		uri = "/resources/css/ui.css";flag = suffixMatcher(uri);
		fileName = uri.substring(0, uri.lastIndexOf("."));
		System.out.println(uri+"::"+flag);

		uri = "/resources/jquery/jquery.min.js";flag = suffixMatcher(uri);
		fileName = uri.substring(0, uri.lastIndexOf("."));
		System.out.println(uri+"::"+flag);

		uri = "lookup/index.html";flag = suffixMatcher(uri);
		fileName = uri.substring(0, uri.lastIndexOf("."));
		System.out.println(uri+"::"+flag);

		uri = "/lookup/index.html";flag = suffixMatcher(uri);
		fileName = uri.substring(0, uri.lastIndexOf("."));
		System.out.println(uri+"::"+flag);

		uri = "/services/sys/resourcesService/findResourcesSiteMenu";
		if (uri.lastIndexOf(".") != -1)
			fileName = uri.substring(0, uri.lastIndexOf("."));
		flag = suffixMatcher(uri);
		System.out.println(uri+flag);*/

		uri = "http://localhost:8080/resources/fonts/fontawesome-webfont.woff2?v=4.5.0";
		flag = suffixMatcher2(uri);
		System.out.println(uri+flag);
		uri = "http://localhost:8080/resources/fonts/fontawesome-webfont.css?v=4.5.0";
		flag = suffixMatcher2(uri);
		System.out.println(uri+flag);
		uri = "http://localhost:8080/resources/fonts/fontawesome-webfont.css";
		flag = suffixMatcher2(uri);
		System.out.println(uri+flag);

		uri = "http://localhost:8080/resources/fonts/fontawesome-webfont.js?v=4.5.0";
		flag = suffixMatcher2(uri);
		if(flag){
			String[] urls = uri.split("[?]");
			if(urls.length>1){
				uri=uri+"&"+111;
			}else{
				uri=uri+"?"+111;
			}
			System.out.println("length:"+urls.length+uri+"+++"+flag);
		}
		uri = "/resources/fonts/fontawesome-webfont.css?v=4.5.0";
		flag = suffixMatcher2(uri);
		if(flag){
			String[] urls = uri.split("[?]");
			if(urls.length>1){
				uri=uri+"&"+111;
			}else{
				uri=uri+"?"+111;
			}
			System.out.println("length:"+urls.length+uri+"+++"+flag);
		}
		uri = "http://localhost:8080/resources/fonts/fontawesome-webfont.js";
		flag = suffixMatcher2(uri);

		if(flag){
			String[] urls = uri.split("[?]");
			if(urls.length>1){
				uri=uri+"&"+111;
			}else{
				uri=uri+"?"+111;
			}
			System.out.println("length:"+urls.length+uri+"+++"+flag);
		}
	}

	private boolean suffixMatcher2(String uri/* ,String suffix */) {
		if (uri.lastIndexOf(".js") != -1)
			return true;
		else if (uri.lastIndexOf(".css") != -1)
			return true;
		else
			return false;
	}

	private boolean suffixMatcher(String uri/* ,String suffix */) {
		if (uri.lastIndexOf(".html") != -1)
			return true;
		else if (uri.lastIndexOf(".htm") != -1)
			return true;
		else if (uri.lastIndexOf("/") == 0){
			System.out.println(uri+":::"+uri.lastIndexOf("/"));
			return true;

		}else
			return false;
	}

}


text:
package gitfs

import (
	"context"
	"fmt"
)

// Get retrieves the named content
func (g *Git) Get(ctx context.Context, name string) ([]byte, error) {
	return g.fs.Get(ctx, name)
}

// Set writes the given content
func (g *Git) Set(ctx context.Context, name string, value []byte) error {
	return g.fs.Set(ctx, name, value)
}

// Delete removes the named entity
func (g *Git) Delete(ctx context.Context, name string) error {
	return g.fs.Delete(ctx, name)
}

// Exists checks if the named entity exists
func (g *Git) Exists(ctx context.Context, name string) bool {
	return g.fs.Exists(ctx, name)
}

// List returns a list of all entities
// e.g. foo, far/bar baz/.bang
// directory separator are normalized using `/`
func (g *Git) List(ctx context.Context, prefix string) ([]string, error) {
	return g.fs.List(ctx, prefix)
}

// IsDir returns true if the named entity is a directory
func (g *Git) IsDir(ctx context.Context, name string) bool {
	return g.fs.IsDir(ctx, name)
}

// Prune removes a named directory
func (g *Git) Prune(ctx context.Context, prefix string) error {
	return g.fs.Prune(ctx, prefix)
}

// String implements fmt.Stringer
func (g *Git) String() string {
	return fmt.Sprintf("gitfs(v0.1.0,path:%s)", g.fs.Path())
}

// Path returns the path to this storage
func (g *Git) Path() string {
	return g.fs.Path()
}

// Fsck checks the storage integrity
func (g *Git) Fsck(ctx context.Context) error {
	// ensure sane git config
	if err := g.fixConfig(ctx); err != nil {
		return fmt.Errorf("failed to fix git config: %w", err)
	}
	return g.fs.Fsck(ctx)
}