/*
+----------------------------------------------------------------------+
| MySQL User Defined Functions Library & Plugin Library |
+----------------------------------------------------------------------+
| Copyright (c) 2007 MySqdLib |
+----------------------------------------------------------------------+
| This program 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 2 of the License, or |
| (at your option) any later version. |
| |
| This program 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 this program; if not, write to the Free Software |
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 |
| USA |
+----------------------------------------------------------------------+
| Authors: MMMed <momed @ users dot1 sourceforge dot2 net> |
+----------------------------------------------------------------------+
*/
/**
* MYSQL_UDF_API
* i hop that ...
* is a set of C macro to keep our code clean, clear and to make it easy to change more quickly
* if MYSQL change here mined about UDF Interface on their SERVER/CLIENT products in the future,
* or mabye I, will do :d
*/
#if defined(WIN32) || defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
# define DLLEXP __declspec(dllexport)
# include <windows.h>
#else
# define DLLEXP
#endif
#ifdef __cplusplus
# define EXTERN extern "C"
#endif
#ifdef STANDARD
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# ifdef __WIN__
typedef unsigned __int64 ulonglong;
typedef __int64 longlong;
# else
typedef unsigned long long ulonglong;
typedef long long longlong;
# endif
#else
# include <my_global.h>
# include <my_sys.h>
# include <m_string.h>
#endif
#include <mysql.h>
#include <ctype.h>
#define MYSQL_UDF_API_VERSION 1.0
#if defined(MYSQL_UDF_API_VERSION)
/* ERRORs handling, */
# define INIT_ERROR(msg) strcpy( message, msg ); return 1
/* ARGUMENTs processing (count, value, length and type), */
# define ARGC args->arg_count
# define ARGV(offset) args->args[offset]
# define ARGL(offset) args->lengths[offset]
# define ARGT(offset) args->arg_type[offset]
# define IS_STRING_ARG(id) ARGT(id) == STRING_RESULT
# define IS_DECIMAL_ARG(id) ARGT(id) == DECIMAL_RESULT
# define IS_REAL_ARG(id) ARGT(id) == REAL_RESULT
# define IS_INT_ARG(id) ARGT(id) == INT_RESULT
# define TO_STRING_ARG(id) ARGT(id) = STRING_RESULT
# define TO_DECIMAL_ARG(id) ARGT(id) = DECIMAL_RESULT
# define TO_REAL_ARG(id) ARGT(id) = REAL_RESULT
# define TO_INT_ARG(id) ARGT(id) = INT_RESULT
# define TO_STRING_ARG_ALL for (uint i=0 ; i < ARGC; i++) TO_STRING_ARG(i)
# define TO_DECIMAL_ARG_ALL for (uint i=0 ; i < ARGC; i++) TO_DECIMAL_ARG(i)
# define TO_REAL_ARG_ALL for (uint i=0 ; i < ARGC; i++) TO_REAL_ARG(i)
# define TO_INT_ARG_ALL for (uint i=0 ; i < ARGC; i++) TO_INT_ARG(i)
/* RETURNs macro, */
# define RETURN_STRING(string) strcpy(result, (char *)string); *length = strlen(result); return result
# define RETURN_DOUBLE(value) return (double) value
# define RETURN_LONG(value) return (longlong) value
# define RETURN_NULL return NULL
/* OTHERs macro, */
# define ISNULL *is_null = 1
# define ISERROR *error = 1
# define NOTNULL *is_null = 0
# define NOTERROR *error = 0
/* FUNCTIONs definitions, */
# define INIT_FUNCTION(function_name) DLLEXP my_bool function_name##_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
# define DEINIT_FUNCTION(function_name) DLLEXP void function_name##_deinit(UDF_INIT *initid)
# define DEFINE_FUNCTION(function_name) EXTERN INIT_FUNCTION(function_name); EXTERN DEINIT_FUNCTION(function_name)
# define DEFINE_STRING_FUNCTION(function_name) DEFINE_FUNCTION(function_name); EXTERN STRING_FUNCTION(function_name)
# define DEFINE_DOUBLE_FUNCTION(function_name) DEFINE_FUNCTION(function_name); EXTERN DOUBLE_FUNCTION(function_name)
# define DEFINE_LONG_FUNCTION(function_name) DEFINE_FUNCTION(function_name); EXTERN LONG_FUNCTION(function_name)
# define LONG_FUNCTION(function_name) DLLEXP longlong function_name(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
# define DOUBLE_FUNCTION(function_name) DLLEXP double function_name(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
# define STRING_FUNCTION(function_name) DLLEXP char* function_name(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error)
# define MAYEBE_NULL(maybe_null) initid->maybe_null = maybe_null
# define MAX_LENGTH(max_len) initid->max_length = max_len
# define DECIMALS(decimals) initid->decimals = decimals
/*THE 3 on one line, with the very basic args_type paraser, */
# define FUNCTION(fname, ftype, arg_t, arg_c, maybenull, maxlen, usage) \
DEFINE_##ftype##_FUNCTION( fname ); \
\
INIT_FUNCTION( fname ) \
{ \
int i = 0, j = 0 ; \
\
if ( ARGC < arg_c ) \
{ \
INIT_ERROR( usage ); \
} \
\
for (; i < strlen( arg_t ); i++ ) \
{ \
switch ( arg_t[i] ) \
{ \
case 'S': TO_STRING_ARG( j ); break; \
case 'R': TO_REAL_ARG( j ); break; \
case 'I': TO_INT_ARG( j ); break; \
case ';': j++ ; break; \
default : INIT_ERROR( "ierror : error while parsing params in FUNCTION " ); \
} \
} \
\
initid->maybe_null = maybenull; \
initid->max_length = maxlen; \
\
return 0; \
} \
\
DEINIT_FUNCTION( fname ) \
{ \
} \
\
ftype##_FUNCTION( fname ) \
#endif
/* ____ENDOFFILE____ */