Module: sip-router
Branch: master
Commit: e6c25ed7be53c692a4cc805a63175a477a6063e8
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=e6c25ed…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)iptel.org>
Date: Wed Nov 11 10:10:52 2009 +0100
xl-lib: shm memory support, regex back reference parsing, xbind
- xl-lib parser supports both pkg and shm memory
- new wrapper functions for the shm memory version:
- xl_shm_parse_format()
- xl_elog_shm_free_all()
- The parser can identify the regular expression back
references (\1, \2, ...) and call a callback function
to farther parse the back reference. Wraper functions
for this:
- xl_parse_format2()
- xl_shm_parse_format2()
- xbind() module function has been introduced that
can be used to bind to the xl API as opposed to
search each exported function individually.
---
modules_s/xlog/xl_lib.c | 146 ++++++++++++++++++++++++++++++++++++++++++-----
modules_s/xlog/xl_lib.h | 30 ++++++++++
modules_s/xlog/xlog.c | 13 +++-
3 files changed, 171 insertions(+), 18 deletions(-)
diff --git a/modules_s/xlog/xl_lib.c b/modules_s/xlog/xl_lib.c
index 1242184..a583f62 100644
--- a/modules_s/xlog/xl_lib.c
+++ b/modules_s/xlog/xl_lib.c
@@ -44,6 +44,7 @@
#include "../../dprint.h"
#include "../../mem/mem.h"
+#include "../../mem/shm_mem.h"
#include "../../ut.h"
#include "../../trim.h"
#include "../../dset.h"
@@ -935,6 +936,13 @@ static void xl_free_select(str *hp)
free_select((select_t*)hp->s);
}
+/* shared memory version of xl_free_select() */
+static void xl_shm_free_select(str *hp)
+{
+ if (hp && hp->s)
+ shm_free_select((select_t*)hp->s);
+}
+
static int xl_get_avp(struct sip_msg *msg, str *res, str *hp, int hi, int hf)
{
int_str name, val;
@@ -987,7 +995,35 @@ static int xl_get_special(struct sip_msg *msg, str *res, str *hp, int
hi, int hf
return 0;
}
-int xl_parse_format(char *s, xl_elog_p *el)
+static int _xl_elog_free_all(xl_elog_p log, int shm)
+{
+ xl_elog_p t;
+ while(log)
+ {
+ t = log;
+ log = log->next;
+ if (t->free_f)
+ (*t->free_f)(&(t->hparam));
+ if (shm)
+ shm_free(t);
+ else
+ pkg_free(t);
+ }
+ return 0;
+}
+
+/* Parse an xl-formatted string pointed by s.
+ * el points to the resulted linked list that is allocated
+ * in shared memory when shm==1 otherwise in pkg memory.
+ * If parse_cb is not NULL then regular expression back references
+ * are passed to the parse_cb function that is supposed to farther parse
+ * the back reference and fill in the xl_elog_t structure.
+ *
+ * Return value:
+ * 0: success
+ * -1: error
+ */
+static int _xl_parse_format(char *s, xl_elog_p *el, int shm, xl_parse_cb parse_cb)
{
char *p, c;
int n = 0;
@@ -1010,7 +1046,10 @@ int xl_parse_format(char *s, xl_elog_p *el)
while(*p)
{
e0 = e;
- e = pkg_malloc(sizeof(xl_elog_t));
+ if (shm)
+ e = shm_malloc(sizeof(xl_elog_t));
+ else
+ e = pkg_malloc(sizeof(xl_elog_t));
if(!e)
goto error;
memset(e, 0, sizeof(xl_elog_t));
@@ -1047,6 +1086,35 @@ int xl_parse_format(char *s, xl_elog_p *el)
e->itf = xl_get_special;
e->hindex = '\t';
break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ /* Regular expression back reference found */
+ if (!parse_cb) {
+ /* There is no callback function, hence the
+ * result will be written as it is. */
+ e->itf = xl_get_special;
+ e->hindex = *p;
+ break;
+ }
+ name.s = p;
+ /* eat all the numeric characters */
+ while ((*(p+1) >= '0') && (*(p+1) <= '9'))
+ p++;
+ name.len = p - name.s + 1;
+ if (parse_cb(&name, shm, e)) {
+ ERR("xlog: xl_parse_format: failed to parse '%.*s'\n",
+ name.len, name.s);
+ goto error;
+ }
+ break;
default:
/* not a special character, it will be just
written to the result as it is */
@@ -1506,14 +1574,17 @@ int xl_parse_format(char *s, xl_elog_p *el)
case '@':
/* fill select structure and call resolve_select */
DBG("xlog: xl_parse_format: @\n");
- n=parse_select(&p, &sel);
+ if (shm)
+ n=shm_parse_select(&p, &sel);
+ else
+ n=parse_select(&p, &sel);
if (n<0) {
ERR("xlog: xl_parse_format: parse_select returned error\n");
goto error;
}
e->itf = xl_get_select;
e->hparam.s = (char*)sel;
- e->free_f = xl_free_select;
+ e->free_f = (shm) ? xl_shm_free_select : xl_free_select;
p--;
break;
case '%':
@@ -1537,11 +1608,43 @@ cont:
return 0;
error:
- xl_elog_free_all(*el);
+ _xl_elog_free_all(*el, shm);
*el = NULL;
return -1;
}
+/* wrapper function for _xl_parse_format()
+ * pkg memory version
+ */
+int xl_parse_format(char *s, xl_elog_p *el)
+{
+ return _xl_parse_format(s, el, 0 /* pkg mem */, NULL /* callback */);
+}
+
+/* wrapper function for _xl_parse_format()
+ * shm memory version
+ */
+int xl_shm_parse_format(char *s, xl_elog_p *el)
+{
+ return _xl_parse_format(s, el, 1 /* shm mem */, NULL /* callback */);
+}
+
+/* wrapper function for _xl_parse_format()
+ * pkg memory version
+ */
+int xl_parse_format2(char *s, xl_elog_p *el, xl_parse_cb cb)
+{
+ return _xl_parse_format(s, el, 0 /* pkg mem */, cb);
+}
+
+/* wrapper function for _xl_parse_format()
+ * shm memory version
+ */
+int xl_shm_parse_format2(char *s, xl_elog_p *el, xl_parse_cb cb)
+{
+ return _xl_parse_format(s, el, 1 /* shm mem */, cb);
+}
+
int xl_print_log(struct sip_msg* msg, xl_elog_p log, char *buf, int *len)
{
int n, h;
@@ -1624,17 +1727,32 @@ done:
return 0;
}
+/* wrapper function for _xl_elog_free_all()
+ * pkg memory version
+ */
int xl_elog_free_all(xl_elog_p log)
{
- xl_elog_p t;
- while(log)
- {
- t = log;
- log = log->next;
- if (t->free_f)
- (*t->free_f)(&(t->hparam));
- pkg_free(t);
- }
+ return _xl_elog_free_all(log, 0 /* pkg mem */);
+}
+
+/* wrapper function for _xl_elog_free_all()
+ * shm memory version
+ */
+int xl_elog_shm_free_all(xl_elog_p log)
+{
+ return _xl_elog_free_all(log, 1 /* shm mem */);
+}
+
+int xl_bind(xl_api_t *xl_api)
+{
+ xl_api->xprint = xl_print_log;
+ xl_api->xparse = xl_parse_format;
+ xl_api->shm_xparse = xl_shm_parse_format;
+ xl_api->xparse2 = xl_parse_format2;
+ xl_api->shm_xparse2 = xl_shm_parse_format2;
+ xl_api->xfree = xl_elog_free_all;
+ xl_api->shm_xfree = xl_elog_shm_free_all;
+ xl_api->xnulstr = xl_get_nulstr;
return 0;
}
diff --git a/modules_s/xlog/xl_lib.h b/modules_s/xlog/xl_lib.h
index a1b5c5d..ca6651e 100644
--- a/modules_s/xlog/xl_lib.h
+++ b/modules_s/xlog/xl_lib.h
@@ -44,16 +44,46 @@ typedef struct _xl_elog
struct _xl_elog *next;
} xl_elog_t, *xl_elog_p;
+/* callback function to parse the regular expression
+ * back references */
+typedef int (*xl_parse_cb) (str *, int, xl_elog_p);
+
typedef int (xl_elog_free_all_f)(xl_elog_p log);
/* int xl_elog_free_all(xl_elog_p log); */
typedef int (xl_parse_format_f)(char *s, xl_elog_p *el);
//int xl_parse_format(char *s, xl_elog_p *el);
+typedef int (xl_parse_format2_f)(char *s, xl_elog_p *el, xl_parse_cb cb);
typedef int (xl_print_log_f)(struct sip_msg*, xl_elog_t*, char*, int*);
//int xl_print_log(struct sip_msg* msg, xl_elog_p log, char *buf, int *len);
typedef str* (xl_get_nulstr_f)(void);
+typedef struct xl_api {
+ xl_print_log_f *xprint;
+ xl_parse_format_f *xparse;
+ xl_parse_format_f *shm_xparse;
+ xl_parse_format2_f *xparse2;
+ xl_parse_format2_f *shm_xparse2;
+ xl_elog_free_all_f *xfree;
+ xl_elog_free_all_f *shm_xfree;
+ xl_get_nulstr_f *xnulstr;
+} xl_api_t;
+
+typedef int (xl_bind_f)(xl_api_t *xl_api);
+
+/* bind to the xl_lib api */
+xl_bind_f xl_bind;
+/* parse and free functions that work with pkg memory */
xl_elog_free_all_f xl_elog_free_all;
xl_parse_format_f xl_parse_format;
+/* parse and free functions that work with shm memory */
+xl_elog_free_all_f xl_elog_shm_free_all;
+xl_parse_format_f xl_shm_parse_format;
+/* parse function supporting regexp back references - pkg mem version */
+xl_parse_format2_f xl_parse_format2;
+/* parse function supporting regexp back references - shm mem version */
+xl_parse_format2_f xl_shm_parse_format2;
+
+
xl_print_log_f xl_print_log;
xl_get_nulstr_f xl_get_nulstr;
diff --git a/modules_s/xlog/xlog.c b/modules_s/xlog/xlog.c
index 612d06f..6de99fa 100644
--- a/modules_s/xlog/xlog.c
+++ b/modules_s/xlog/xlog.c
@@ -67,10 +67,15 @@ static cmd_export_t cmds[]={
ONREPLY_ROUTE | BRANCH_ROUTE},
{"xdbg", xdbg, 1, xdbg_fixup, REQUEST_ROUTE | FAILURE_ROUTE |
ONREPLY_ROUTE | BRANCH_ROUTE},
- {"xprint", (cmd_function)xl_print_log, NO_SCRIPT, 0, 0},
- {"xparse", (cmd_function)xl_parse_format, NO_SCRIPT, 0, 0},
- {"xfree", (cmd_function)xl_elog_free_all, NO_SCRIPT, 0, 0},
- {"xnulstr", (cmd_function)xl_get_nulstr, NO_SCRIPT, 0, 0},
+ {"xbind", (cmd_function)xl_bind, NO_SCRIPT, 0, 0},
+ {"xprint", (cmd_function)xl_print_log, NO_SCRIPT, 0, 0},
+ {"xparse", (cmd_function)xl_parse_format, NO_SCRIPT, 0, 0},
+ {"shm_xparse", (cmd_function)xl_shm_parse_format, NO_SCRIPT, 0, 0},
+ {"xparse2", (cmd_function)xl_parse_format2, NO_SCRIPT, 0, 0},
+ {"shm_xparse2", (cmd_function)xl_shm_parse_format2, NO_SCRIPT, 0, 0},
+ {"xfree", (cmd_function)xl_elog_free_all, NO_SCRIPT, 0, 0},
+ {"shm_xfree", (cmd_function)xl_elog_shm_free_all, NO_SCRIPT, 0, 0},
+ {"xnulstr", (cmd_function)xl_get_nulstr, NO_SCRIPT, 0, 0},
{0,0,0,0,0}
};