summaryrefslogtreecommitdiffstats
path: root/tinyDEMO/dssl.rl
diff options
context:
space:
mode:
Diffstat (limited to 'tinyDEMO/dssl.rl')
-rw-r--r--tinyDEMO/dssl.rl358
1 files changed, 358 insertions, 0 deletions
diff --git a/tinyDEMO/dssl.rl b/tinyDEMO/dssl.rl
new file mode 100644
index 0000000..cc4d104
--- /dev/null
+++ b/tinyDEMO/dssl.rl
@@ -0,0 +1,358 @@
+/*
+* Copyright (C) 2009 Mamadou Diop.
+*
+* Contact: Mamadou Diop <diopmamadou(at)doubango.org>
+*
+* This file is part of Open Source Doubango Framework.
+*
+* DOUBANGO is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* DOUBANGO is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with DOUBANGO.
+*
+*/
+#include "dssl.h"
+
+#include "tsk_debug.h"
+#include "tsk_memory.h"
+#include "tsk_string.h"
+#include "tsk_ragel_state.h"
+
+#include <string.h>
+
+#define DEBUG_PARSER 0
+
+#define set_level(_lv) if(opt) opt->lv = _lv;
+
+char* replace_param(char* pivot, int index_1, int index_2, tsk_params_L_t* params)
+{
+ char* pname = tsk_null;
+ char* ret = tsk_null;
+ const tsk_param_t* p;
+ //tsk_size_t len = tsk_strlen(pivot);
+ //tsk_bool_t parenthesis = tsk_false;
+ int i1, i2;
+
+ /* whether there are parenthesis around the param */
+ if((i1 = tsk_strindexOf((pivot + index_1), tsk_strlen((pivot + index_1)), "(")) == 2
+ && (i2 = tsk_strindexOf((pivot + index_1 + i1), tsk_strlen((pivot + index_1 + i1)), ")")) != -1)
+ {
+ pname = tsk_strndup((pivot + index_1 + i1 + 1), (i2 - i1 + 1));
+ index_2 = index_1 + i1 + i2 + 1;
+ }
+ else{
+ pname = tsk_strndup((pivot + index_1 + 2/*$$*/), (index_2 - index_1 - 2));
+ }
+
+ if((p = tsk_params_get_param_by_name(params, pname))){
+ tsk_strncat(&ret, pivot, index_1);
+ tsk_strncat(&ret, p->value, tsk_strlen(p->value));
+ tsk_strncat(&ret, (pivot + index_2), (tsk_strlen(pivot) - index_2));
+ }
+ else{
+ TSK_DEBUG_WARN("Failed to find param [%s]", pname);
+ }
+
+ TSK_FREE(pname);
+ return ret;
+}
+
+tsk_bool_t next_not_(const char* p, const char* pe, char c)
+{
+ if((p && pe) && (pe-p) >=2){
+ return (*p == c && *(p + 1) == c) ? tsk_false : tsk_true;
+ }
+ return tsk_true;
+}
+#define next_not_hyphens(p, pe) next_not_(p, pe, '-')
+#define next_not_arobases(p, pe) next_not_(p, pe, '@')
+#define next_not_percents(p, pe) next_not_(p, pe, '%')
+#define next_not_redirs(p, pe) next_not_(p, pe, '>')
+
+/***********************************
+* Ragel state machine.
+*/
+%%{
+ machine demo_machine_parser_cmd;
+
+ action tag{
+ tag_start = p;
+#if DEBUG_PARSER
+ // - TSK_DEBUG_INFO("tag=%s", tag_start);
+#endif
+ }
+
+ action create_option{
+#if DEBUG_PARSER
+ TSK_DEBUG_INFO("create_option");
+#endif
+ TSK_OBJECT_SAFE_FREE(opt);
+ opt = opt_create_null();
+ }
+
+ action add_option{
+#if DEBUG_PARSER
+ TSK_DEBUG_INFO("add_option");
+#endif
+ tsk_list_push_back_data(cmd->opts, (void**)&opt);
+ }
+
+ action set_opt_value{
+ if(opt){
+ int index_1, index_2;
+ char* newval = tsk_null;
+ TSK_PARSER_SET_STRING(opt->value);
+ /* trim both: left and right */
+ tsk_strtrim_both(&opt->value);
+ /* replace params */
+replace:
+ if((index_1 = tsk_strindexOf(opt->value, tsk_strlen(opt->value), "$$")) != -1){
+ if((index_2 = tsk_strindexOf((opt->value + index_1), tsk_strlen((opt->value + index_1)), " ")) != -1){
+ newval = replace_param(opt->value, index_1, (index_1 + index_2), params);
+ }
+ else{
+ newval = replace_param(opt->value, index_1, tsk_strlen(opt->value), params);
+ }
+ if(newval){
+ TSK_FREE(opt->value);
+ opt->value = newval;
+
+ /* again */
+ goto replace;
+ }
+ }
+#if DEBUG_PARSER
+ TSK_DEBUG_INFO("set_opt_value [%d] '%s'", opt->type, opt->value);
+#endif
+ }
+ }
+
+ action set_sidparam_value{
+ TSK_PARSER_SET_STRING(cmd->sidparam);
+#if DEBUG_PARSER
+ TSK_DEBUG_INFO("set_sidparam_value '%s'", cmd->sidparam);
+#endif
+ }
+
+ action create_param{
+#if DEBUG_PARSER
+ TSK_DEBUG_INFO("create_param");
+#endif
+ TSK_OBJECT_SAFE_FREE(param);
+ param = tsk_param_create_null();
+ }
+
+ action add_param{
+#if DEBUG_PARSER
+ TSK_DEBUG_INFO("add_param");
+#endif
+ tsk_params_add_param_2(&params, param);
+ TSK_OBJECT_SAFE_FREE(param);
+ }
+
+ action set_param_value{
+ if(param){
+ TSK_PARSER_SET_STRING(param->value);
+ /* trim both: left and right */
+ tsk_strtrim_both(&param->value);
+#if DEBUG_PARSER
+ TSK_DEBUG_INFO("set_param_value [%s] '%s'", param->name, param->value);
+#endif
+ }
+ }
+
+ action set_param_name{
+ if(param){
+ TSK_PARSER_SET_STRING(param->name);
+ }
+ }
+
+ action is_comment{
+#if DEBUG_PARSER
+ TSK_PARSER_SET_STRING(temp);
+ TSK_DEBUG_INFO("is_comment '%s'", temp);
+#endif
+ // *comment = tsk_true;
+ // TSK_OBJECT_SAFE_FREE(opts);
+ }
+
+ action next_not_reserved{
+ next_not_hyphens(p, pe)
+ && next_not_arobases(p, pe)
+ && next_not_percents(p, pe)
+ && next_not_redirs(p, pe)
+ && (p && *p != '\n')
+ && (p && *p != '#')
+ }
+
+ action next_not_newline{
+ (p && *p != '\n')
+ }
+
+ action option_error{
+ TSK_PARSER_SET_STRING(temp);
+ TSK_DEBUG_ERROR("'%s' is not a valid option.", temp);
+ }
+
+ action command_error{
+ TSK_PARSER_SET_STRING(temp);
+ TSK_DEBUG_ERROR("'%s' is not a valid command.", temp);
+ }
+
+ action level_error{
+ TSK_PARSER_SET_STRING(temp);
+ TSK_DEBUG_ERROR("'%s' is not a valid level.", temp);
+ }
+
+ SP = " ";
+ LF = "\n";
+ CR = "\r";
+ endline = ("\n" | "\r");
+ equal = "=";
+ hyphens = "-" {2,};
+ plusplus = "+" {2,};
+ percents = "%" {2,};
+ redirs = ">" {2,};
+ sharp = "#";
+ arobases = "@" {2,};
+
+ command = (("audio"i | "a"i) %{ cmd->type = cmd_audio; } |
+ ("audiovideo"i | "av"i) %{ cmd->type = cmd_audiovideo; } |
+ ("config-session"i | "css"i) %{ cmd->type = cmd_config_session; } |
+ ("config-stack"i | "cst"i) %{ cmd->type = cmd_config_stack; } |
+ ("dtmf"i) %{ cmd->type = cmd_dtmf; } |
+ ("dump"i | "d"i) %{ cmd->type = cmd_dump; } |
+ ("ect"i) %{ cmd->type = cmd_ect; } |
+ ("exit"i | "e"i | "quit"i | "q"i) %{ cmd->type = cmd_exit; } |
+ ("file"i | "f"i) %{ cmd->type = cmd_file; } |
+ ("hangup"i | "hu"i) %{ cmd->type = cmd_hangup; } |
+ ("help"i | "h"i) %{ cmd->type = cmd_help; } |
+ ("hold"i | "ho"i) %{ cmd->type = cmd_hold; } |
+ ("large-message"i | "lm"i) %{ cmd->type = cmd_large_message; } |
+ ("message"i | "m"i) %{ cmd->type = cmd_message; } |
+ ("options"i | "opt"i) %{ cmd->type = cmd_options; } |
+ ("publish"i | "pub"i) %{ cmd->type = cmd_publish; } |
+ ("register"i | "reg"i) %{ cmd->type = cmd_register; } |
+ ("resume"i | "res"i) %{ cmd->type = cmd_resume; } |
+ ("run"i | "r"i) %{ cmd->type = cmd_run; } |
+ ("scenario"i | "sn"i) %{ cmd->type = cmd_scenario; } |
+ "sleep"i %{ cmd->type = cmd_sleep; } |
+ "sms"i %{ cmd->type = cmd_sms; } |
+ "stop"i %{ cmd->type = cmd_stop; } |
+ ("subscribe"i | "sub"i) %{ cmd->type = cmd_subscribe; } |
+ ("video"i | "v"i) %{ cmd->type = cmd_video; }
+ )** >10 |
+ (any*) >tag >0 %command_error;
+
+ key = ("amf"i % { opt->type = opt_amf; } |
+ "caps"i % { opt->type = opt_caps; } |
+ "dhcpv4"i % { opt->type = opt_dhcpv4; } |
+ "dhcpv6"i % { opt->type = opt_dhcpv6; } |
+ "dname"i % { opt->type = opt_amf; } |
+ "dns-naptr"i % { opt->type = opt_dname; } |
+ "event"i % { opt->type = opt_event; } |
+ ("expires"i | "xp"i) % { opt->type = opt_expires; } |
+ "from"i % { opt->type = opt_from; } |
+ "header"i % { opt->type = opt_header; } |
+ "impi"i % { opt->type = opt_impi; } |
+ "impu"i % { opt->type = opt_impu; } |
+ "ipv6"i % { opt->type = opt_ipv6; } |
+ "local-ip"i % { opt->type = opt_local_ip; } |
+ "local-port"i % { opt->type = opt_local_port; } |
+ "opid"i % { opt->type = opt_opid; } |
+ ("password"i | "pwd"i) % { opt->type = opt_password; } |
+ "path"i % { opt->type = opt_path; } |
+ ("payload"i | "pay"i) % { opt->type = opt_payload; } |
+ "pcscf-ip"i % { opt->type = opt_pcscf_ip; } |
+ "pcscf-port"i % { opt->type = opt_pcscf_port; } |
+ "pcscf-trans"i % { opt->type = opt_pcscf_trans; } |
+ "realm"i % { opt->type = opt_realm; } |
+ "sec"i % { opt->type = opt_sec; } |
+ "sid"i % { opt->type = opt_sid; } |
+ "sigcomp-id"i % { opt->type = opt_sigcomp_id; } |
+ "silent"i % { opt->type = opt_silent; } |
+ "smsc"i % { opt->type = opt_smsc; } |
+ "stun-ip"i % { opt->type = opt_stun_ip; } |
+ "stun-pwd"i % { opt->type = opt_stun_pwd; } |
+ "stun-port"i % { opt->type = opt_stun_port; } |
+ "stun-usr"i % { opt->type = opt_stun_usr; } |
+ "to"i % { opt->type = opt_to; }
+ )** >10 |
+ (any*) >tag >0 %option_error;
+
+ level_stack = ("stack"i | "st"i);
+ level_session = ("session"i | "ss"i);
+ level_action= ("action"i | "request"i | "a"i | "r"i);
+ level = ( (level_stack %{ set_level(lv_stack); } | level_session %{ set_level(lv_session); } | level_action %{ set_level(lv_action); })** > 10
+ | (any*)>tag >0 %level_error ) :> space*;
+ value = (any when next_not_reserved)*>tag;
+ option = key>tag:>SP* <:value %set_opt_value (arobases level)?;
+
+ pname = (any when next_not_newline)*>tag %set_param_name;
+ pvalue = value;
+ param = pname :>(space | '\n')+ <:pvalue %set_param_value;
+
+ main := |*
+ (plusplus command) >100 { };
+ (hyphens option>create_option %add_option) >99 { };
+ (percents param>create_param %add_param) >98 { };
+ (redirs "("?<: value %set_sidparam_value :>")"?) >97 { };
+ (sharp (any when next_not_newline)* >tag %is_comment) >96 { };
+ any >0 { };
+ *|;
+}%%
+
+cmd_t* dssl_parse(const char *buffer, tsk_size_t size, tsk_bool_t *comment, tsk_params_L_t* params)
+{
+ int cs = 0;
+ const char *p = buffer;
+ const char *pe;
+ const char *eof;
+ opt_t* opt = tsk_null;
+ tsk_param_t* param = tsk_null;
+ cmd_t *cmd = cmd_create_null();
+ char* temp = tsk_null;
+ int index;
+
+ const char *ts = tsk_null, *te = tsk_null;
+ int act = 0;
+
+ const char *tag_start = tsk_null;
+
+ /* global vars and initilization (Ragel) */
+ %%write data;
+ %%write init;
+
+ /* default values */
+ *comment = tsk_false;
+
+ /* only parse one line */
+ if((index = tsk_strindexOf(p, size, "\n")) != -1){
+ pe = eof = (p + index + 1/*\n*/);
+ }
+ else{
+ pe = eof = p + size;
+ }
+
+ /* exec */
+ %%write exec;
+
+ if( cs < %%{ write first_final; }%% ){
+ TSK_DEBUG_ERROR("Failed to parse [%s] command-Line.", p);
+ TSK_OBJECT_SAFE_FREE(cmd);
+ }
+ TSK_OBJECT_SAFE_FREE(opt);
+ TSK_OBJECT_SAFE_FREE(param);
+ TSK_FREE(temp);
+
+ return cmd;
+}
+
OpenPOWER on IntegriCloud