소스 검색

Add macro value parsing code.

tags/0.6.0
Vsevolod Stakhov 11 년 전
부모
커밋
fc9dbea5f5
1개의 변경된 파일92개의 추가작업 그리고 0개의 파일을 삭제
  1. 92
    0
      src/rcl/rcl_parser.c

+ 92
- 0
src/rcl/rcl_parser.c 파일 보기

@@ -953,6 +953,92 @@ rspamd_cl_parse_after_value (struct rspamd_cl_parser *parser, struct rspamd_cl_c
return TRUE;
}

/**
* Handle macro data
* @param parser
* @param chunk
* @param err
* @return
*/
static gboolean
rspamd_cl_parse_macro_value (struct rspamd_cl_parser *parser,
struct rspamd_cl_chunk *chunk, struct rspamd_cl_macro *macro, GError **err)
{
const guchar *p, *c;

p = chunk->pos;

switch (*p) {
case '"':
/* We have macro value encoded in quotes */
c = p;
rspamd_cl_chunk_skipc (chunk, *p);
p ++;
if (!rspamd_cl_lex_json_string (parser, chunk, err)) {
return FALSE;
}

if (!macro->handler (c + 1, chunk->pos - c - 2, macro->ud, err)) {
return FALSE;
}
p = chunk->pos;
break;
case '{':
/* We got a multiline macro body */
rspamd_cl_chunk_skipc (chunk, *p);
p ++;
/* Skip spaces at the beginning */
while (p < chunk->end) {
if (g_ascii_isspace (*p)) {
rspamd_cl_chunk_skipc (chunk, *p);
p ++;
}
else {
break;
}
}
c = p;
while (p < chunk->end) {
if (*p == '}') {
break;
}
rspamd_cl_chunk_skipc (chunk, *p);
p ++;
}
if (!macro->handler (c, p - c, macro->ud, err)) {
return FALSE;
}
rspamd_cl_chunk_skipc (chunk, *p);
p ++;
break;
default:
/* Macro is not enclosed in quotes or braces */
c = p;
while (p < chunk->end) {
if (rspamd_cl_lex_is_atom_end (*p)) {
break;
}
rspamd_cl_chunk_skipc (chunk, *p);
p ++;
}
if (!macro->handler (c, p - c, macro->ud, err)) {
return FALSE;
}
break;
}

/* We are at the end of a macro */
/* Skip ';' and space characters and return to previous state */
while (p < chunk->end) {
if (!g_ascii_isspace (*p) && *p != ';') {
break;
}
rspamd_cl_chunk_skipc (chunk, *p);
p ++;
}
return TRUE;
}

/**
* Handle the main states of rcl parser
* @param parser parser structure
@@ -1089,6 +1175,12 @@ rspamd_cl_state_machine (struct rspamd_cl_parser *parser, GError **err)
}
break;
case RSPAMD_RCL_STATE_MACRO:
if (!rspamd_cl_parse_macro_value (parser, chunk, macro, err)) {
parser->prev_state = parser->state;
parser->state = RSPAMD_RCL_STATE_ERROR;
return FALSE;
}
parser->state = parser->prev_state;
break;
default:
/* TODO: add all states */

Loading…
취소
저장