#include <cx/string.h>
#include <cx/linked_list.h>
#include <cx/array_list.h>
#include <cx/compare.h>
#include "../public/nsapi.h"
#include "object.h"
#include "util.h"
#include "pool.h"
#include "../daemon/func.h"
httpd_object* object_new(
pool_handle_t *pool,
char *name) {
httpd_object *obj = pool_malloc(pool,
sizeof(httpd_object));
obj->pool = pool;
obj->name = name;
obj->path =
NULL;
obj->dt = pool_calloc(pool,
NUM_NSAPI_TYPES -
1,
sizeof(
struct dtable));
obj->nd =
NUM_NSAPI_TYPES -
1;
return obj;
}
void object_free(httpd_object *obj) {
}
int object_add_directive(httpd_object *obj, directive *dir,
int dt) {
dtable *l = object_get_dtable(obj, dt);
if(l->ndir >= l->alloc) {
l->alloc +=
8;
directive **drs = pool_realloc(obj->pool, l->dirs, (l->alloc)*
sizeof(
void*));
if(!drs) {
l->alloc -=
8;
return -
1;
}
l->dirs = drs;
}
l->dirs[l->ndir++] = dir;
return 0;
}
httpd_objset* objset_create(
pool_handle_t *pool) {
httpd_objset *os = pool_malloc(pool,
sizeof(httpd_objset));
os->obj = pool_calloc(pool,
2,
sizeof(
void*));
os->pos =
0;
return os;
}
void objset_add_object(
pool_handle_t *p, httpd_objset *os, httpd_object *obj) {
if(os->pos !=
0 && os->pos %
2 ==
0) {
os->obj = pool_realloc(p, os->obj, (os->pos +
2) *
sizeof(
void*));
}
os->obj[os->pos] = obj;
os->pos++;
}
void httpobjconf_add_object(HTTPObjectConfig *conf, httpd_object *obj) {
conf->nobj++;
conf->objects = realloc(conf->objects, conf->nobj *
sizeof(
void*));
conf->objects[conf->nobj -
1] = obj;
}
void nsapi_context_next_stage(NSAPIContext *context) {
context->dtable_index =
0;
context->objset_index = -
1;
context->last_req_code =
REQ_NOACTION;
}
Expression* condition_create(
pool_handle_t *pool, CxList *tokens) {
size_t pos =
0;
NSAPIExpression *expression = expr_parse_logical_expr(pool, tokens, &pos);
if(!expression || pos != tokens->size) {
return NULL;
}
return NULL;
}
typedef struct {
pool_handle_t *pool;
CxList *op_stack;
CxList *ex_stack;
CxList *tokens;
size_t *pos;
WSBool expect_value;
WSBool expect_arg;
} ExprParser;
typedef struct {
NSAPIExpressionOperator operator;
cxstring identifier;
int expect_value;
int open_parenthesis;
} ExprOpStackItem;
static void expr_free(
pool_handle_t *pool, NSAPIExpression *expr) {
if(expr->left) {
expr_free(pool, expr->left);
}
if(expr->right) {
expr_free(pool, expr->right);
}
if(expr->type ==
NSAPI_EXPRESSION_STRING && expr->value.str.ptr) {
pool_free(pool, (
char*)expr->value.str.ptr);
}
else if(expr->type ==
NSAPI_EXPRESSION_VARIABLE && expr->value.var.ptr) {
pool_free(pool, (
char*)expr->value.var.ptr);
}
pool_free(pool, expr);
}
static NSAPIExpressionOperator expr_operator(cxstring token) {
if(!cx_strcmp(token, cx_str(
","))) {
return NSAPI_EXPRESSION_ARG;
}
else if(!cx_strcmp(token, cx_str(
"+"))) {
return NSAPI_EXPRESSION_ADD;
}
else if(!cx_strcmp(token, cx_str(
"-"))) {
return NSAPI_EXPRESSION_SUB;
}
else if(!cx_strcmp(token, cx_str(
"*"))) {
return NSAPI_EXPRESSION_MUL;
}
else if(!cx_strcmp(token, cx_str(
"/"))) {
return NSAPI_EXPRESSION_DIV;
}
else if(!cx_strcmp(token, cx_str(
"%"))) {
return NSAPI_EXPRESSION_MOD;
}
else if(!cx_strcmp(token, cx_str(
"."))) {
return NSAPI_EXPRESSION_STRCAT;
}
else if(!cx_strcmp(token, cx_str(
"not")) || !cx_strcmp(token, cx_str(
"!"))) {
return NSAPI_EXPRESSION_NOT;
}
else if(!cx_strcmp(token, cx_str(
"and")) || !cx_strcmp(token, cx_str(
"&&"))) {
return NSAPI_EXPRESSION_AND;
}
else if(!cx_strcmp(token, cx_str(
"or")) || !cx_strcmp(token, cx_str(
"||"))) {
return NSAPI_EXPRESSION_OR;
}
else if(!cx_strcmp(token, cx_str(
"xor")) || !cx_strcmp(token, cx_str(
"^"))) {
return NSAPI_EXPRESSION_XOR;
}
else if(!cx_strcmp(token, cx_str(
"=="))) {
return NSAPI_EXPRESSION_EQ;
}
else if(!cx_strcmp(token, cx_str(
"!="))) {
return NSAPI_EXPRESSION_NEQ;
}
else if(!cx_strcmp(token, cx_str(
">"))) {
return NSAPI_EXPRESSION_GT;
}
else if(!cx_strcmp(token, cx_str(
"<"))) {
return NSAPI_EXPRESSION_LT;
}
else if(!cx_strcmp(token, cx_str(
">="))) {
return NSAPI_EXPRESSION_GE;
}
else if(!cx_strcmp(token, cx_str(
"<="))) {
return NSAPI_EXPRESSION_LE;
}
else if(!cx_strcmp(token, cx_str(
"="))) {
return NSAPI_EXPRESSION_WILDCARD_MATCH;
}
else if(!cx_strcmp(token, cx_str(
"=~"))) {
return NSAPI_EXPRESSION_REGEX_MATCH;
}
else if(!cx_strcmp(token, cx_str(
"!~"))) {
return NSAPI_EXPRESSION_REGEX_MISMATCH;
}
else if(!cx_strcmp(token, cx_str(
"defined"))) {
return NSAPI_EXPRESSION_VALUE_DEFINED;
}
else if(!cx_strcmp(token, cx_str(
"-d"))) {
return NSAPI_EXPRESSION_DIR_EXISTS;
}
else if(!cx_strcmp(token, cx_str(
"-e"))) {
return NSAPI_EXPRESSION_FILE_DIR_EXISTS;
}
else if(!cx_strcmp(token, cx_str(
"-f"))) {
return NSAPI_EXPRESSION_FILE_EXISTS;
}
else if(!cx_strcmp(token, cx_str(
"-l"))) {
return NSAPI_EXPRESSION_SYMLINK_EXISTS;
}
else if(!cx_strcmp(token, cx_str(
"-r"))) {
return NSAPI_EXPRESSION_FILE_READABLE;
}
else if(!cx_strcmp(token, cx_str(
"-s"))) {
return NSAPI_EXPRESSION_FILE_SIZE;
}
return NSAPI_EXPRESSION_NOOP;
}
static int token_is_int(cxstring token) {
if(token.length ==
0) {
return 0;
}
size_t start =
0;
if(token.ptr[
0] ==
'-' || token.ptr[
0] ==
'+') {
if(token.length <
2) {
return 0;
}
start++;
}
for(
size_t i=start;i<token.length;i++) {
if(!isdigit(token.ptr[i])) {
return 0;
}
}
return 1;
}
static int expr_set_value(
pool_handle_t *pool, NSAPIExpression *expr, cxstring token) {
if(token.length >=
2 && token.ptr[
0] ==
'\"' && token.ptr[token.length-
1] ==
'\"') {
expr->value.str = cx_strcast(cx_strdup_a(pool_allocator(pool), cx_strsubsl(token,
1, token.length-
2)));
expr->type =
NSAPI_EXPRESSION_STRING;
}
else if(token.length >=
2 && token.ptr[
0] ==
'$' && isalpha(token.ptr[
1])) {
expr->value.var = cx_strcast(cx_strdup_a(pool_allocator(pool), cx_strsubs(token,
1)));
expr->type =
NSAPI_EXPRESSION_VARIABLE;
}
else if(token_is_int(token)) {
if(!util_strtoint(token.ptr, &expr->value.i)) {
return 1;
}
expr->type =
NSAPI_EXPRESSION_INT;
}
else if(!strcmp(token.ptr,
"true")) {
expr->type =
NSAPI_EXPRESSION_BOOL;
expr->value.b =
1;
}
else if(!strcmp(token.ptr,
"false")) {
expr->type =
NSAPI_EXPRESSION_BOOL;
expr->value.b =
0;
}
else {
return 1;
}
return 0;
}
cxstring expr_next_token(CxList *tokens,
size_t *pos) {
cxstring *token = cxListAt(tokens, *pos);
if(token) {
(*pos)++;
return *token;
}
return (cxstring){
NULL,
0};
}
NSAPIExpression* expr_parser_pop(ExprParser *parser) {
CxList *stack = parser->ex_stack;
if(stack->size ==
0) {
return NULL;
}
NSAPIExpression *ret = *((NSAPIExpression**)cxListAt(stack, stack->size-
1));
cxListRemove(stack, stack->size-
1);
return ret;
}
static int expr_add_operator(ExprParser *parser, ExprOpStackItem *op) {
NSAPIExpression *exp = pool_malloc(parser->pool,
sizeof(NSAPIExpression));
exp->operator = op->operator;
if(op->expect_value) {
if(op->operator ==
NSAPI_EXPRESSION_ARG && !parser->expect_arg) {
pool_free(parser->pool, exp);
parser->expect_value =
TRUE;
parser->expect_arg =
FALSE;
return 0;
}
exp->type =
NSAPI_EXPRESSION_UNARY;
exp->left = expr_parser_pop(parser);
exp->right =
NULL;
}
else if(exp->operator ==
NSAPI_EXPRESSION_CALL) {
exp->operator =
NSAPI_EXPRESSION_NOOP;
exp->left =
NULL;
exp->right =
NULL;
exp->type =
NSAPI_EXPRESSION_IDENTIFIER;
exp->value.identifier = op->identifier;
}
else {
exp->type =
NSAPI_EXPRESSION_BINARY;
exp->right = expr_parser_pop(parser);
exp->left = expr_parser_pop(parser);
}
if(!exp->left && !exp->right && exp->operator !=
NSAPI_EXPRESSION_NOOP) {
return 1;
}
cxListAdd(parser->ex_stack, &exp);
parser->expect_value =
TRUE;
parser->expect_arg =
FALSE;
return 0;
}
static int expr_add_func(ExprParser *parser, ExprOpStackItem *func) {
NSAPIExpression *exp = pool_malloc(parser->pool,
sizeof(NSAPIExpression));
if(!exp) {
return 1;
}
exp->type =
NSAPI_EXPRESSION_IDENTIFIER;
exp->operator =
NSAPI_EXPRESSION_CALL;
exp->left =
NULL;
exp->right =
NULL;
exp->value.str = func->identifier;
if(parser->ex_stack->size >
0) {
NSAPIExpression *top = *((NSAPIExpression**)cxListAt(parser->ex_stack, parser->ex_stack->size -
1));
if(top && top->operator ==
NSAPI_EXPRESSION_ARG) {
exp->left = top;
cxListRemove(parser->ex_stack, parser->ex_stack->size -
1);
}
}
if(cxListAdd(parser->ex_stack, &exp)) {
return 1;
}
parser->expect_value =
FALSE;
return 0;
}
static int expr_add_value(ExprParser *parser, cxstring token) {
NSAPIExpression *exp = pool_malloc(parser->pool,
sizeof(NSAPIExpression));
ZERO(exp,
sizeof(NSAPIExpression));
if(expr_set_value(parser->pool, exp, token)) {
return 1;
}
cxListAdd(parser->ex_stack, &exp);
if(parser->expect_arg) {
ExprOpStackItem argList;
argList.expect_value =
TRUE;
argList.identifier = (cxstring){
NULL,
0};
argList.open_parenthesis =
FALSE;
argList.operator =
NSAPI_EXPRESSION_ARG;
if(expr_add_operator(parser, &argList)) {
return 1;
}
}
parser->expect_value =
FALSE;
parser->expect_arg =
FALSE;
return 0;
}
static int token_is_identifier(cxstring token) {
if(token.length ==
0) {
return 0;
}
if(!isalpha(token.ptr[
0])) {
return 0;
}
for(
int i=
1;i<token.length;i++) {
if(!isalnum(token.ptr[i])) {
return 0;
}
}
if(!cx_strcmp(token, cx_str(
"true")) || !cx_strcmp(token, cx_str(
"false"))) {
return 0;
}
return 1;
}
static NSAPIExpression* expr_parse_expr(ExprParser *parser) {
CxList *op_stack = parser->op_stack;
CxList *ex_stack = parser->ex_stack;
cxstring token = expr_next_token(parser->tokens, parser->pos);
for(;token.ptr;token=expr_next_token(parser->tokens, parser->pos)) {
NSAPIExpressionOperator op = expr_operator(token);
if(op !=
NSAPI_EXPRESSION_NOOP) {
ExprOpStackItem new_op;
new_op.operator = op;
new_op.identifier = (cxstring){
NULL,
0};
new_op.expect_value = parser->expect_value;
new_op.open_parenthesis =
FALSE;
while(op_stack->size >
0) {
ExprOpStackItem *stack_item = cxListAt(op_stack, op_stack->size-
1);
if(stack_item->operator ==
NSAPI_EXPRESSION_NOOP) {
break;
}
if(op >= stack_item->operator) {
break;
}
if(expr_add_operator(parser, stack_item)) {
return NULL;
}
cxListRemove(op_stack, op_stack->size-
1);
}
cxListAdd(op_stack, &new_op);
parser->expect_value =
TRUE;
parser->expect_arg =
FALSE;
}
else if(token.length ==
1 && token.ptr[
0] ==
'(') {
ExprOpStackItem *prev_op =
NULL;
if(op_stack->size >
0) {
prev_op = cxListAt(op_stack, op_stack->size -
1);
}
if(prev_op && prev_op->operator ==
NSAPI_EXPRESSION_CALL) {
prev_op->open_parenthesis =
TRUE;
parser->expect_arg =
TRUE;
}
else {
ExprOpStackItem new_op;
new_op.operator =
NSAPI_EXPRESSION_NOOP;
new_op.identifier = (cxstring){
NULL,
0};
new_op.expect_value =
0;
new_op.open_parenthesis =
TRUE;
cxListAdd(op_stack, &new_op);
}
parser->expect_value =
TRUE;
}
else if(token.length ==
1 && token.ptr[
0] ==
')') {
int found_open_bracket =
FALSE;
ExprOpStackItem stack_item;
while(op_stack->size >
0) {
ExprOpStackItem *stack_item_ptr = cxListAt(op_stack, op_stack->size-
1);
stack_item = *stack_item_ptr;
cxListRemove(op_stack, op_stack->size-
1);
if(stack_item.open_parenthesis) {
found_open_bracket =
TRUE;
break;
}
else {
if(expr_add_operator(parser, &stack_item)) {
return NULL;
}
}
}
if(!found_open_bracket) {
return NULL;
}
if(stack_item.operator ==
NSAPI_EXPRESSION_CALL) {
if(expr_add_func(parser, &stack_item)) {
return NULL;
}
}
parser->expect_value =
FALSE;
parser->expect_arg =
FALSE;
}
else if(token_is_identifier(token)) {
ExprOpStackItem new_op;
new_op.operator =
NSAPI_EXPRESSION_CALL;
new_op.identifier = token;
new_op.expect_value =
0;
new_op.open_parenthesis =
FALSE;
cxListAdd(op_stack, &new_op);
parser->expect_value =
FALSE;
parser->expect_arg =
FALSE;
}
else {
if(expr_add_value(parser, token)) {
return NULL;
}
}
}
while(op_stack->size >
0) {
ExprOpStackItem *stack_item = cxListAt(op_stack, op_stack->size-
1);
if(stack_item->open_parenthesis) {
return NULL;
}
if(expr_add_operator(parser, stack_item)) {
return NULL;
}
cxListRemove(op_stack, op_stack->size-
1);
}
if(ex_stack->size !=
1) {
return NULL;
}
NSAPIExpression **ret = cxListAt(ex_stack,
0);
return *ret;
}
NSAPIExpression* expr_parse_logical_expr(
pool_handle_t *pool, CxList *tokens,
size_t *pos) {
CxList *op_stack = cxArrayListCreate(pool_allocator(pool),
NULL,
sizeof(ExprOpStackItem),
32);
CxList *ex_stack = cxArrayListCreate(pool_allocator(pool),
NULL,
sizeof(NSAPIExpression*),
32);
ExprParser parser;
parser.pool = pool;
parser.op_stack = op_stack;
parser.ex_stack = ex_stack;
parser.tokens = tokens;
parser.pos = pos;
parser.expect_value =
TRUE;
parser.expect_arg =
FALSE;
NSAPIExpression *ret = expr_parse_expr(&parser);
cxListDestroy(op_stack);
cxListDestroy(ex_stack);
return ret;
}
int condition_evaluate(Condition *condition, Session *sn, Request *rq) {
return 1;
}