--- /dev/null
+#ifndef API_SWIG_H
+#define API_SWIG_H
+
+#include <idzebra/res.h>
+#include <idzebra/api.h>
+
+typedef short IDZEBRA_RES;
+#define RES_LIST char** res_args
+
+/*
+-------------------------------------------------------------------------------
+ API Calls
+-------------------------------------------------------------------------------
+*/
+void idzebra_api_init(void);
+
+char **api_errors(void);
+
+int api_check_error(void);
+
+void api_clear_error(void);
+
+
+ZebraService idzebra_start (RES_LIST);
+
+IDZEBRA_RES idzebra_stop(ZebraService zs);
+
+
+ZebraHandle idzebra_open (ZebraService zs, RES_LIST);
+
+IDZEBRA_RES idzebra_close(ZebraHandle zh);
+
+IDZEBRA_RES idzebra_samplefunc(ZebraHandle zh, RES_LIST);
+
+
+/*
+-------------------------------------------------------------------------------
+ Utility functions for argument handling
+-------------------------------------------------------------------------------
+*/
+
+#if __STDC_VERSION__ < 199901L
+# if __GNUC__ >= 2
+# define __func__ __FUNCTION__
+# else
+# define __func__ "<unknown>"
+# endif
+#endif
+
+#define API_SET_CONTEXT api_error_context = __func__
+
+void args_parse_res (Res r,
+ const char **valid_args,
+ Res skip,
+ char **args);
+
+void args_use (ZebraHandle zh,
+ Res r,
+ Res rr,
+ int mandatory,
+ const char **args);
+
+#define ARG_MODE_OPTIONAL 0
+#define ARG_MODE_MANDATORY 1
+#define ARG_MODE_FORCE 2
+
+#define RES_OPEN(var,def,over) \
+ var = res_open(def, over); \
+ res_set(var,"__context__", __func__ ); \
+
+#define ARGS_INIT \
+ Res local = 0; \
+ Res func_res = 0; \
+ Res temp_res = 0; \
+
+#define ARGS_PARSE(...) \
+ { \
+ const char *vargs[] = { __VA_ARGS__ , 0 }; \
+ RES_OPEN(func_res, 0, 0); \
+ RES_OPEN(local, 0, 0); \
+ args_parse_res(func_res, vargs, local, res_args); \
+ } \
+
+#define ARGS_APPLY \
+ temp_res = res_add_over(zh->session_res, func_res); \
+
+#define ARGS_PROCESS(mode, ...) \
+ { \
+ const char *vargs[] = { __VA_ARGS__ , 0 }; \
+ args_use(zh, local, func_res, mode, vargs); \
+ } \
+
+#define ARGS_REVOKE \
+ { \
+ const char **used; \
+ res_remove_over(temp_res); \
+ used = res_get_array(local, "_used"); \
+ args_use(zh, zh->session_res, 0, ARG_MODE_FORCE, used); \
+ free_array(used); \
+ } \
+
+#define ARGS_DONE \
+ if (func_res) res_close(func_res); \
+ if (local) res_close(local); \
+
+#endif /* API_SWIG_H */
-/* $Id: res.h,v 1.7 2005-09-13 11:51:06 adam Exp $
+/* $Id: res.h,v 1.8 2005-09-15 09:27:18 pop Exp $
Copyright (C) 1995-2005
Index Data ApS
YAZ_EXPORT
ZEBRA_RES res_get_int(Res r, const char *name, int *val);
+
+/* == pop ================================================================= */
+
+YAZ_EXPORT
+Res res_add_over (Res p, Res t);
+
+YAZ_EXPORT
+void res_remove_over (Res r);
+
+YAZ_EXPORT
+void res_close_over (Res r);
+
+YAZ_EXPORT
+void res_add (Res r, const char *name, const char *value);
+
+YAZ_EXPORT
+char **res_2_array (Res r);
+
+YAZ_EXPORT
+char **res_get_array(Res r, const char* name);
+
+YAZ_EXPORT
+void res_dump (Res r, int level);
+
YAZ_END_CDECL
#endif
-## $Id: Makefile.am,v 1.32 2005-08-19 09:21:34 adam Exp $
+## $Id: Makefile.am,v 1.33 2005-09-15 09:27:18 pop Exp $
noinst_PROGRAMS = apitest kdump
libidzebra_api_la_SOURCES = dir.c dirs.c trav.c kinput.c kcompare.c \
attribute.c symtab.c recindex.c recstat.c lockutil.c \
- zebraapi.c zinfo.c invstat.c sortidx.c compact.c zsets.c zrpn.c \
+ zebraapi.c api_swig.c \
+ zinfo.c invstat.c sortidx.c compact.c zsets.c zrpn.c \
rank1.c trunc.c retrieve.c extract.c rankstatic.c \
index.h recindex.h recindxp.h \
zinfo.h zserver.h zvrank.c limit.c kcontrol.c
--- /dev/null
+#include <idzebra/api_swig.h>
+#include <idzebra/res.h>
+#include <idzebra/api.h>
+#include <stdarg.h>
+#include "index.h"
+
+#define DEFAULT_APPROX_LIMIT 2000000000
+
+/* == API errors, debug ==================================================== */
+static Res api_error = 0;
+const char* api_error_context = 0;
+void api_add_error(const char *fmt, ...);
+void api_clear_error(void);
+void free_array(const char **args);
+ZebraHandle zebra_get_handle (ZebraService zs);
+
+
+/* == API init, destroy =================================================== */
+void idzebra_api_init(void)
+{
+ yaz_log_init_prefix("API_SWIG");
+ yaz_log(YLOG_LOG, "IDZebra API initialized");
+}
+
+/* == Service start/stop =================================================== */
+
+ZebraService idzebra_start(RES_LIST)
+{
+ ZebraService zs = 0;
+
+ ARGS_INIT;
+ API_SET_CONTEXT;
+
+ ARGS_PARSE ("configName",
+ "chdir",
+ "modulePath",
+ "profilePath",
+ "register",
+ "shadow",
+ "isam",
+ "keyTmpDir",
+ "setTmpDir",
+ "lockDir");
+
+ zs = zebra_start_res(res_get(func_res,"configName"), NULL, func_res);
+
+ /* Function resources are kept for service (zs->global_res); */
+ func_res = 0;
+ ARGS_DONE;
+
+ return (zs);
+}
+
+IDZEBRA_RES idzebra_stop(ZebraService zs)
+{
+ /* Global res have an over part here */
+ res_close_over(zs->global_res);
+ return (zebra_stop(zs));
+}
+
+/* == Session open/close =================================================== */
+ZebraHandle idzebra_open (ZebraService zs, RES_LIST)
+{
+
+ ZebraHandle zh;
+
+ ARGS_INIT;
+ API_SET_CONTEXT;
+
+ ARGS_PARSE ("tempfiles",
+ "openRW",
+ "memmax",
+ "encoding",
+ "estimatehits",
+ "staticrank");
+
+ zh = zebra_open(zs, func_res);
+
+ /* Function resources are kept for session (zh->res->over_res); */
+ func_res = 0;
+ ARGS_DONE;
+
+ yaz_log (YLOG_DEBUG, "zebra_open zs=%p returns %p", zs, zh);
+
+ return (zh);
+}
+
+IDZEBRA_RES idzebra_close(ZebraHandle zh)
+{
+ res_close_over(zh->session_res);
+ return (zebra_close(zh));
+}
+/* == Sample function == =================================================== */
+IDZEBRA_RES idzebra_samplefunc(ZebraHandle zh, RES_LIST)
+{
+ ARGS_INIT;
+ API_SET_CONTEXT;
+ ARGS_PARSE("strucc");
+ ARGS_PROCESS(ARG_MODE_OPTIONAL,"encoding");
+ ARGS_APPLY;
+
+ yaz_log (YLOG_DEBUG, "Got strucc:%s\n",res_get(zh->res,"strucc"));
+ res_dump (zh->res,0);
+
+ ARGS_REVOKE;
+ ARGS_DONE;
+ return (ZEBRA_OK);
+}
+
+
+/*
+-------------------------------------------------------------------------------
+ Utility functions for argument handling
+-------------------------------------------------------------------------------
+*/
+void arg_parse_res (Res r,
+ const char **valid_args,
+ Res skip,
+ char *name, char *value)
+{
+ if ((name) && (value)) {
+ int i = 0;
+ int gotit = 0;
+ while (valid_args[i]) {
+ if (!strcmp(name, valid_args[i])) {
+ res_set(r, name, value);
+ gotit = 1;
+ break;
+ }
+ i++;
+ }
+ if (!gotit)
+ yaz_log (YLOG_DEBUG, "skip: %s=%s",name, value);
+ res_add (skip, name, value);
+ }
+}
+
+void args_parse_res (Res r,
+ const char **valid_args,
+ Res skip,
+ char **args)
+{
+ char *argname;
+ char *argvalue;
+ int i = 0;
+ if (args) {
+ while (args[i] && args[i+1]) {
+ argname = args[i++];
+ argvalue = args[i++];
+ arg_parse_res (r, valid_args, skip, argname, argvalue);
+ }
+ }
+}
+
+/* == special resource handlers ============================================ */
+
+void idzebra_res_encoding (ZebraHandle zh, const char *value)
+{
+ if (value)
+ zebra_octet_term_encoding(zh, value);
+ else
+ zebra_octet_term_encoding(zh, "ISO-8859-1");
+
+}
+
+void idzebra_res_estimatehits (ZebraHandle zh, const char *value)
+{
+ int val = 0;
+ if (value)
+ if (! (sscanf(value, "%d", &val) == 1))
+ api_add_error( "Expected integer value for 'estimatehits'");
+
+ zebra_set_approx_limit(zh, val);
+}
+
+void idzebra_res_staticrank (ZebraHandle zh, const char *value)
+{
+ int val = 0;
+ if (value)
+ if (! (sscanf(value, "%d", &val) == 1))
+ api_add_error( "Expected integer value for 'estimatehits'");
+
+ zh->m_staticrank = val;
+}
+
+/* == applying and revoking call-scope resources =========================== */
+
+void arg_use (ZebraHandle zh,
+ Res r,
+ Res rr,
+ int mode,
+ const char *name)
+{
+ if (name) {
+ const char *value = res_get(r, name);
+ int gotit = 0;
+
+ /* in FORCE mode resource is used with default value also */
+ if ((value) || (mode & ARG_MODE_FORCE)) {
+
+ /* encoding */
+ if (!strcmp(name,"encoding")) {
+ idzebra_res_encoding(zh, value);
+ gotit = 1;
+ }
+
+ /* estimatehits */
+ else if (!strcmp(name,"estimatehits")) {
+ idzebra_res_estimatehits(zh, value);
+ gotit = 1;
+ }
+
+ /* staticrank */
+ else if (!strcmp(name,"staticrank")) {
+ idzebra_res_staticrank(zh, value);
+ gotit = 1;
+ }
+
+ /* collects provided arguments in order to revoke them
+ at the end of the function */
+ if (gotit) {
+ if (! (mode & ARG_MODE_FORCE)) res_add(r, "_used", name);
+ if ( (rr) && (name) && (value) ) res_add(rr, name, value);
+ }
+ } else {
+ /* value missing */
+ if (mode & ARG_MODE_MANDATORY)
+ api_add_error( "Missing mandatory argument '%s'", name);
+ }
+ }
+}
+
+void args_use (ZebraHandle zh,
+ Res r,
+ Res rr,
+ int mode,
+ const char **args)
+{
+ int i = 0;
+ if (args) {
+ while (args[i]) {
+ arg_use (zh, r, rr, mode, args[i++]);
+ }
+ }
+}
+
+/* == API errors =========================================================== */
+
+void api_add_error(const char *fmt, ...)
+{
+
+ va_list ap;
+ char buf[4096];
+ const char *context;
+ va_start(ap, fmt);
+
+#ifdef WIN32
+ _vsnprintf(buf, sizeof(buf)-1, fmt, ap);
+#else
+/* !WIN32 */
+#if HAVE_VSNPRINTF
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+#else
+ vsprintf(buf, fmt, ap);
+#endif
+#endif
+
+ va_end (ap);
+
+ if (! api_error)
+ api_error = res_open(0,0);
+
+ if (api_error_context)
+ context = api_error_context;
+ else
+ context = "<unknown>";
+
+ res_add(api_error, context, buf);
+}
+
+char **api_errors(void)
+{
+ static char **res = 0;
+
+ res = res_2_array(api_error);
+ if (!res) {
+ res = xmalloc(sizeof(char *));
+ res[0] = 0 ;
+ }
+ return (&res[0]);
+
+}
+
+
+int api_check_error(void)
+{
+ if (api_error)
+ return (1);
+ else
+ return (0);
+}
+
+void api_clear_error(void)
+{
+ if (api_error)
+ res_close(api_error);
+ api_error = 0;
+}
+
+void free_array(const char **args)
+{
+ int i = 0;
+ if (args) {
+ while (args[i]) {
+ xfree((char *) args[i]);
+ i++;
+ }
+ xfree (args);
+ }
+}
-/* $Id: zebraapi.c,v 1.185 2005-09-13 11:51:06 adam Exp $
+/* $Id: zebraapi.c,v 1.186 2005-09-15 09:27:18 pop Exp $
Copyright (C) 1995-2005
Index Data ApS
zh->shadow_enable = 1;
zh->m_staticrank = 0;
+ zebra_open_res(zh);
+
default_encoding = res_get_def(zh->session_res, "encoding", "ISO-8859-1");
zh->iconv_to_utf8 =
-/* $Id: res.c,v 1.45 2005-09-13 11:51:11 adam Exp $
+/* $Id: res.c,v 1.46 2005-09-15 09:27:18 pop Exp $
Copyright (C) 1995-2005
Index Data ApS
#include <yaz/yaz-util.h>
#include <idzebra/res.h>
+#define YLOG_RES 0
+
struct res_entry {
char *name;
char *value;
fclose(fr);
return ZEBRA_OK;
}
-
Res res_open(Res def_res, Res over_res)
{
Res r;
-
r = (Res) xmalloc(sizeof(*r));
r->first = r->last = NULL;
r->def_res = def_res;
}
return ZEBRA_FAIL;
}
+
+/* == pop ================================================================= */
+Res res_add_over (Res p, Res t)
+{
+ if ((!p) || (!t))
+ return (0);
+
+ while (p->over_res)
+ p = p->over_res;
+
+ p->over_res = t;
+ return (p);
+}
+
+void res_remove_over (Res r)
+{
+ if (!r)
+ return;
+ r->over_res = 0;
+}
+
+void res_close_over (Res r)
+{
+ if (!r)
+ return;
+ if (r->over_res)
+ res_close(r->over_res);
+ r->over_res = 0;
+}
+
+void res_add (Res r, const char *name, const char *value)
+{
+ struct res_entry *re;
+ assert (r);
+ if ((name) && (value))
+ yaz_log (YLOG_RES, "res_add res=%p, name=%s, value=%s", r, name, value);
+
+ re = add_entry (r);
+ re->name = xstrdup (name);
+ re->value = xstrdup_env (value);
+}
+
+char **res_2_array (Res r)
+{
+ struct res_entry *re;
+ int i = 0;
+ char **list;
+
+ if (!r)
+ return 0;
+
+ list = xmalloc(sizeof(char *));
+
+ for (re = r->first; re; re=re->next) {
+ list = xrealloc(list, ((i+3) * sizeof(char *)));
+ list[i++] = strdup(re->name);
+ if (re->value)
+ list[i++] = strdup(re->value);
+ else
+ list[i++] = strdup("");
+ yaz_log(YLOG_RES, "res2array: %s=%s",re->name, re->value);
+ }
+ list[i++] = 0;
+ return (list);
+}
+
+char **res_get_array(Res r, const char* name)
+{
+ struct res_entry *re;
+ int i = 0;
+ char **list;
+
+ if (!r)
+ return 0;
+
+ list = xmalloc(sizeof(char *));
+
+ for (re = r->first; re; re=re->next)
+ if (re->value && !yaz_matchstr (re->name, name))
+ {
+ list = xrealloc(list, (i+2) * sizeof(char *));
+ list[i++] = xstrdup(re->value);
+ }
+
+ if (i == 0)
+ return (res_get_array(r->def_res, name));
+
+ list[i++] = 0;
+ return (list);
+}
+
+void res_dump (Res r, int level)
+{
+ struct res_entry *re;
+
+ if (!r)
+ return;
+
+ printf ("RES:\n", level * 4,"");
+
+ for (re = r->first; re; re=re->next) {
+ printf("%*s - %s:='%s'\n",level * 4,"",re->name,re->value);
+ }
+
+ if (r->def_res) {
+ printf ("%*s DEF ",level * 4,"");
+ res_dump (r->def_res, level + 1);
+ }
+
+ if (r->over_res) {
+ printf ("%*s OVER ",level * 4,"");
+ res_dump (r->over_res, level + 1);
+ }
+}