/*
    LIBZ
    Copyright (C) 1998, 2000  VVK (valera@sbnet.ru), CNII Center, Moscow

    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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#ifndef __ZDEFS_A
#define __ZDEFS_A

#ifndef __OS2__
#define __OS2__
#endif

/* Define if you need to in order for stat and other things to work.  */
/* #undef _POSIX_SOURCE */

/* Define to empty if the keyword does not work.  */
/* #undef const */

/* Define to empty if the keyword does not work.  */
#define inline

/* Define to `long' if <sys/types.h> doesn't define.  */
/* #undef off_t */

/* Define to `int' if <sys/types.h> doesn't define.  */
#define pid_t            int

/* Define to `unsigned' if <sys/types.h> doesn't define.  */
/* #undef size_t */

/* Define as the return type of signal handlers (int or void).  */
#define RETSIGTYPE       void

/* Define if `struct tm' has a `tm_zone' member */
/* #undef HAVE_TM_ZONE */

/* Define if you have the external array `tzname' */
#define HAVE_TZNAME

/* Define if the memcmp function is not available, or does not work
   on 8-bit data (like the one on SunOS 4.1.3).  */
/* #undef MEMCMP_BROKEN */

/* Define if the `S_IS*' macros in <sys/stat.h> do not work properly.  */
/* #undef STAT_MACROS_BROKEN */

/* Define if the qsort does not work properly.  */
/* #undef QSORT_BROKEN */

/* Define if you have the ANSI C header files.  */
#define STDC_HEADERS     1

/* Define if you can safely include both <sys/time.h> and <time.h>.  */
/* #undef TIME_WITH_SYS_TIME */

/* Define if your <sys/time.h> declares struct tm.  */
/* #undef TM_IN_SYS_TIME */

/* Define if the setvbuf function takes the buffering type as its second
   argument and the buffer pointer as the third, as on System V
   before release 3.  */
/* #undef SETVBUF_REVERSED */

/* The number of bytes in a int.  */
#define SIZEOF_INT       4

/* The number of bytes in a long.  */
#define SIZEOF_LONG      4

/* The number of bytes in a short.  */
#define SIZEOF_SHORT     2

/* Define if you have the bcmp function.  */
/* #undef HAVE_BCMP */

/* Define if you have the bcopy function.  */
/* #undef HAVE_BCOPY */

/* Define if you have the bfill function.  */
/* #undef HAVE_BFILL */

/* Define if you have the bmove function.  */
/* #undef HAVE_BMOVE */

/* Define if you have the bzero function.  */
/* #undef HAVE_BZERO */

/* Define if you have the ftime function.  */
#define HAVE_FTIME       1

/* Define if you have the gettimeofday function.  */
/* #undef HAVE_GETTIMEOFDAY */

/* Define if you have the gmtime_r function.  */
/* #undef HAVE_GMTIME_R */

/* Define if you have the index function.  */
/* #undef HAVE_INDEX */

/* Define if you have the localtime_r function.  */
/* #undef HAVE_LOCALTIME_R */

/* Define if you have the lstat function.  */
/* #undef HAVE_LSTAT */

/* Define if you have the memcmp function.  */
#define HAVE_MEMCMP      1

/* Define if you have the memcpy function.  */
#define HAVE_MEMCPY      1

/* Define if you have the memmove function.  */
#define HAVE_MEMMOVE     1

/* Define if you have the memset function.  */
#define HAVE_MEMSET      1

/* Define if you have the mmap function.  */
/* #undef HAVE_MMAP */

/* Define if you have the qsort function.  */
#define HAVE_QSORT       1

/* Define if you have the rindex function.  */
/* #undef HAVE_RINDEX */

/* Define if you have the signal function.  */
#define HAVE_SIGNAL      1

/* Define if you have the snprintf function.   */
/* #undef HAVE_SNPRINTF */

/* Define if you have the strcasecmp function.   */
#define HAVE_STRCASECMP  1
#define strcasecmp       stricmp

/* Define if you have the strchr function.  */
#define HAVE_STRCHR      1

/* Define if you have the strdup function.  */
#define HAVE_STRDUP      1

/* Define if you have the strerror function.  */
#define HAVE_STRERROR    1

/* Define if you have the strncasecmp function.  */
#undef HAVE_STRNCASECMP
#define strncasecmp      strnicmp

/* Define if you have the strrchr function.  */
#define HAVE_STRRCHR     1

/* Define if you have the strstr function.  */
#define HAVE_STRSTR      1

/* Define if you have the strtol function.  */
#define HAVE_STRTOL      1

/* Define if you have the timegm function.  */
/* #undef HAVE_TIMEGM */

/* Define if you have the <sys/dir.h> header file.  */
/* #undef HAVE_SYS_DIR_H */

/* Define if you have the <dirent.h> header file.  */
#define HAVE_DIRENT_H    1

/* Define if you have the <limits.h> header file. */
#define HAVE_LIMITS_H    1

/* Define if you have the <memory.h> header file.  */
#define HAVE_MEMORY_H    1

/* Define if you have the <ndir.h> header file.  */
/* #undef HAVE_NDIR_H */

/* Define if you have the <signal.h> header file.  */
#define HAVE_SIGNAL_H    1

/* Define if you have the <string.h> header file.  */
#define HAVE_STRING_H    1

/* Define if you have the <strings.h> header file.  */
/* #undef HAVE_STRINGS_H */

/* Define if you have the <sys/dir.h> header file.  */
/* #undef HAVE_SYS_DIR_H */

/* Define if you have the <sys/ndir.h> header file.  */
/* #undef HAVE_SYS_NDIR_H */

/* Define if you have the <sys/time.h> header file.  */
/* #undef HAVE_SYS_TIME_H */

/* Define if you have the <sys/types.h> header file.  */
#define HAVE_SYS_TYPES_H 1

/* Define if you have the <sys/wait.h> header file.  */
/* #undef HAVE_SYS_WAIT_H */

/* Define if you have the <unistd.h> header file.  */
/* #undef HAVE_UNISTD_H */

/* Define if you have the <winsock.h> header file.  */
/* #undef HAVE_WINSOCK_H */

/* Define if you have the <winsock2.h> header file.  */
#define HAVE_WINSOCK2_H  1

/* Define if you have the m library (-lm).  */
#define HAVE_LIBM        1

/* Define if you support case independent file names */
#define HAVE_CASEINDEP_FILE_NAMES 1

/* - OS/2 specials - */
#define __ZEXPORTP(type) extern type
#define __ZEXPORTF(type) type _Export
#define __ZEXPORTV(type) extern type
#define __ZEXPORTD(type) type _Export
#define __ZIMPORTP(type) extern type
#define __ZIMPORTF(type) type
#define __ZIMPORTV(type) extern type
#define __ZIMPORTD(type) type

#endif

#ifndef __ZTYPES_A
#define __ZTYPES_A

#ifndef __ZDEFS_A
#error Should be included through "zdefs.h"
#endif

#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

typedef enum{ False = 0, True = 1 } Boolean;

/* zint_t, zshort_t & zoff_t */
#if SIZEOF_INT == 4
# define zint_t        int
# define __ZINT(x)     x
# define _ZINT_FORMAT  ""
# define SIZEOF_ZINT   4
#elif SIZEOF_SHORT == 4
# define zint_t        short
# define __ZINT(x)     x
# define _ZINT_FORMAT  ""
# define SIZEOF_ZINT   4
#elif SIZEOF_LONG == 4
# define __ZINT(x)     x##L
# define zint_t        long
# define _ZINT_FORMAT  "l"
# define SIZEOF_ZINT   4
#elif SIZEOF_INT > 4
# define zint_t        int
# define __ZINT(x)     x
# define _ZINT_FORMAT  ""
# define SIZEOF_ZINT   8
#else
# error Unable to define four bytes interger variable
#endif

# define zlong_t       long

#if SIZEOF_LONG == 2
# define zshort_t      short
# define SIZEOF_ZSHORT 2
#elif SIZEOF_INT == 2
# define zshort_t      int
# define SIZEOF_ZSHORT 2
#elif SIZEOF_SHORT > 2
# define zshort_t      short
# define SIZEOF_ZSHORT 4
#elif SIZEOF_INT > 2
# define zshort_t      int
# define SIZEOF_ZSHORT 4
#else
# error Unable to define two bytes interger variable
#endif

#if SIZEOF_LONG == 4
# define zoff_t        long
# define _ZOFF_FORMAT  "l"
#else
# define zoff_t        zint_t
# define _ZOFF_FORMAT  _ZINT_FORMAT
#endif

/* Export/import */
/* ZEXT => _ZEXPORTV/_ZIMPORTV - объявление переменной в .h файле */
/* ZDEF => _ZEXPORTD/_ZIMPORTD - export переменной в .c файле */
/* ZAPI => _ZEXPORTP/_ZEXPORTP - объявление функции в .h файле */
/* ZFUN => _ZEXPORTF/_ZEXPORTF - export функции в .c файле */

#if defined( _ZAPI )
#  if defined( _ZEXPORT )
#    if defined( __ZEXPORTD )
#      define ZDEF(type) __ZEXPORTD(type)
#    endif
#    if defined( __ZEXPORTV )
#      define ZEXT(type) __ZEXPORTV(type)
#    endif
#    if defined( __ZEXPORTP )
#      define ZAPI(type) __ZEXPORTP(type)
#    endif
#    if defined( __ZEXPORTF )
#      define ZFUN(type) __ZEXPORTF(type)
#    endif
#  else
#    if defined( __ZIMPORTD )
#      define ZDEF(type) __ZIMPORTD(type)
#    endif
#    if defined( __ZIMPORTV )
#      define ZEXT(type) __ZIMPORTV(type)
#    endif
#    if defined( __ZIMPORTP )
#      define ZAPI(type) __ZIMPORTP(type)
#    endif
#    if defined( __ZIMPORTF )
#      define ZFUN(type) __ZIMPORTF(type)
#    endif
#  endif
#endif

#if !defined( ZDEF )
#define ZDEF(type) type
#endif
#if !defined( ZEXT )
#define ZEXT(type) extern type
#endif
#if !defined( ZAPI )
#define ZAPI(type) type
#endif
#if !defined( ZFUN )
#define ZFUN(type) type
#endif

/* */
#if defined( __MSDOS__ ) || defined( __WIN32__ ) || defined( __OS2__ )
#define READ_B_MODE          "rb"
#define READ_T_MODE          "r"
#define WRITE_B_MODE         "wb"
#define WRITE_T_MODE         "w"
#define WRITEREAD_B_MODE     "w+b"
#define WRITEREAD_T_MODE     "w+"
#define READWRITE_B_MODE     "r+b"
#define READWRITE_T_MODE     "r+"
#define APPEND_T_MODE        "a"
#define APPEND_B_MODE        "ab"
#define APPENDUPDATE_T_MODE  "a+"
#define APPENDUPDATE_B_MODE  "a+b"
#else
#define READ_B_MODE          "r"
#define READ_T_MODE          "r"
#define WRITE_B_MODE         "w"
#define WRITE_T_MODE         "w"
#define WRITEREAD_B_MODE     "w+"
#define WRITEREAD_T_MODE     "w+"
#define READWRITE_B_MODE     "r+"
#define READWRITE_T_MODE     "r+"
#define APPEND_T_MODE        "a"
#define APPEND_B_MODE        "a"
#define APPENDUPDATE_T_MODE  "a+"
#define APPENDUPDATE_B_MODE  "a+"
#endif

#if defined( __MSDOS__ ) || defined( __WIN32__ ) || defined( __OS2__ )
#define SLASH          '\\'
#define SLASH_STRING   "\\"
#else
#define SLASH          '/'
#define SLASH_STRING   "/"
#endif

/* Various structures & function types */
#ifndef __MSVC__
#pragma warn -stu
#endif

/* libz's */
struct zconfsec_t;
struct zconfdef_t;
struct zcontext_t;
struct zdatacoll_t;
struct zdataheap_t;
struct zfileobject_t;
struct zioinfo_t;
struct zparamcoll_t;
struct zprocdir_t;
struct zprocess_t;
struct zrbtree_t;
struct zreplace_t;
struct zreplacerule_t;
struct zstatus_t;
struct zstrbuf_t;
struct zstrcoll_t;
struct ztempfile_t;
struct ztimeval_t;

typedef int (*zcmp_t)( const void *, const void *);
typedef int (*zstrcmp_t)( const char *, const char *);
typedef void (*zdelete_t)( struct zcontext_t *, void *);
typedef void (*zprinterror_t)( struct zcontext_t *, unsigned zint_t, const char *);
typedef char *(*zprocessstring_t)( struct zcontext_t *, char *);
typedef void (*zmemfail_t)( struct zcontext_t *, const char *);
typedef int (*zwrite_t)( struct zcontext_t *, const char *, int);
typedef Boolean (*zflush_t)( struct zcontext_t * );

/* libzex's */
struct zcginput_t;
struct zcgidata_t;
struct zcgi_tplvalue_t;
struct zsocket_t;
struct ztelnet_t;

/* Useful macroses */
#define ZMIN(x,y)      (((x) < (y)) ? (x) : (y))
#define ZMAX(x,y)      (((x) > (y)) ? (x) : (y))

#define ZEOL(x)        ((x) == '\0' || (x) == '\n')

#define ZCOUNT(x,d)    (((x) / (d)) + (((x) % (d)) != 0 ? 1 : 0))
#define _ZALIGN(x,d)   (((x) % (d)) != 0 ? (((x) / (d) + 1) * (d)) : (x))
#define ZALIGN(x,d)    if( ((x) % (d)) != 0 ) (x) = ((x) / (d) + 1) * (d)

#define ZOFFSET(type,member) ((int) (&(((type *) 0)->member)))

#define zSetFlags(x,flags)                 ((x) |= (flags))
#define zUnsetFlags(x,flags)               ((x) &= ~(flags))
#define zUnsetFlagsEx(x,flags,t)           ((x) &= ~((t) (flags)))
#define zCheckFlags(x,flags)               ((x) & (flags))
#define zLeaveFlags(x,flags)               ((x) &= (flags))
#define zTestFlags(x,flags,value)          (((x) & (flags)) == (value))
#define zHasFlags(x,flags)                 (((x) & (flags)) == (flags))

#define ZXOR(b,p)      (((~(b)) & (p)) | ((b) & (~(p))))

#define zLowerHex(x)   (("0123456789abcdef")[(int) ((x) & 0xf)])
#define zUpperHex(x)   (("0123456789ABCDEF")[(int) ((x) & 0xf)])

#define zRecode(s,t) \
    do               \
    {                \
      register unsigned char *ptr = (unsigned char *) s, c; \
      for( ; (c = *ptr) != '\0'; ptr++) *ptr = t[ c ]; \
    } while( 0 )

#define zRecode8(s,t) \
    do                \
    {                 \
      register unsigned char *ptr = (unsigned char *) (s), c; \
      for( ; (c = *ptr) != '\0'; ptr++) \
        if( (c & 0x80) != 0 && (c = ((unsigned char *) (t))[c & 0x7f]) != '\0' ) \
          *ptr = c; \
    } while( 0 )

#define ZCLOSE(x) \
    do            \
    {             \
      if( (x) != -1 ){ close( (x) ); (x) = -1; } \
    } while( 0 )

#define ZFCLOSE(x) \
    do             \
    {              \
      if( (x) != NULL ){ fclose( (x) ); (x) = NULL; } \
    } while( 0 )

#define ZGET_ARG(x)                                     \
    if( argv[argx][2] != '\0' )                         \
      (x) = &argv[argx][2];                             \
    else if( argx == argc-1 || argv[argx+1][0] == '-' ) \
      ((x) = NULL, doUsage = True);                     \
    else                                                \
      (x) = argv[++argx]

/* Function stuff */
#if !defined( HAVE_QSORT ) || defined( QSORT_BROKEN )
void _bsd_qsort( void *a, size_t n, size_t es, zcmp_t cmp);
#define ZQSORT _bsd_qsort
#else
#define ZQSORT qsort
#endif

#ifdef __cplusplus
}
#endif

#endif

#ifndef __ZCFG_A
#define __ZCFG_A

/***************************************************************************/
/*                                                                         */
/*  Russian & ukrainian support                                            */
/*                                                                         */
/***************************************************************************/

/* Поддерживать ли русский язык вообще */
#define RUSSIAN_SUPPORT

/* Выдавать ли сообщения на русском языке (заодно должна быть включена
   поддержка русского языка) */
#define RUSSIAN_INTERFACE

/* Поддерживать ли украинский язык (заодно должна быть включена поддержка
   русского языка) */
/* #define UKRAINIAN_SUPPORT */

/* Выдавать ли сообщения на украинском языке (заодно должна быть включена
   поддержка украинского языка) */
/* Недоделано - нужна помощь переводчика!!! */
/* #define UKRAINIAN_INTERFACE */

/* Кодировка исходных текстов (библиотек, исполняемых модулей и т.д.)
   Если Вы меняете значение этого параметра, то ОБЯЗАНЫ соответствующим
   образом изменить кодировку исходных тестов. И наоборот, при изменении
   кодировки исходных текстов необходимо поправить значение этого
   параметра.
   Возможные значения: *_koi, *_win, *_alt, *_iso, *_mac */
#define LOCAL_CHARSET                  arc_alt

/* Поддерживать ли непосредственно кодировку ISO для русского языка или же
   ее аналог для платформы SCO UNIX */
/* #define APPLY_CYR_SCO */

/* Поддерживать ли вместо альтернативной кодировки (в украинском варианте)
   ее аналог с именем RUSCII, который является официальным стандартом
   кодировки на Украине (должна быть включена поддержка украинского языка) */
/* #define APPLY_CYR_RUSCII */

/* Использовать ли для KOI8 кодировки имя koi8-u вместо koi8-r (в теге
   META генерируемых HTML страниц; должна быть включена поддержка
   украинского языка) */
/* #define APPLY_CYR_KOI8_U_NAME */

/* Использовать ли для кодировки ISO вместо предусмотренной стандартом
   буквы DJE более необходимую букву GHE (в украинском варианте) */
/* #define APPLY_ISO_GHE */

/* Кодировка консольного окна (если отличается от LOCAL_CHARSET).
   Для OS/2 & MS Windows она всегда альтернативная. */
#if defined( __MSDOS__ ) || defined( __WIN32__ ) || defined( __OS2__ )
#define REMOTE_CHARSET                 ZCHARSET_CYR_ALT
#endif

#if defined( __WIN32__ ) || defined( _WIN32 ) || defined( WIN32 )
#define ARGS_CHARSET                   ZCHARSET_CYR_WIN
#else
#define ARGS_CHARSET                   ZCHARSET_UNKNOWN
#endif

/* Имя переменной окружения, которую установливает Web сервер Russian Apache,
   и значение которой - кодировка клиента (пользовательского браузера) */
#define HTTPD_LOCAL_CHARSET_ENVIRONMENT     "SOURCE_CHARSET"
#define HTTPD_REMOTE_CHARSET_ENVIRONMENT    "CHARSET"

/* Имя параметра в CGI запросе, значением которого является установленная
   кодировка клиента */
#define ZCGI_PARAM_CHARSET              "cs"

/* Имя параметра в CGI запросе, значением которого является пробная строка
   из русских букв */
#define ZCGI_PARAM_CSWORD               "word"

/* Пробная строка из русских букв для ZCGI_PARAM_CSWORD */
#define ZCGI_DEFAULT_CSWORD             "ок"

/***************************************************************************/
/*                                                                         */
/*  CGI Environment                                                        */
/*                                                                         */
/***************************************************************************/

/* Значения каких переменных окружения устанавливать в zcgiGetEnvironment() */
/* #define _ZCGI_AUTH_TYPE */
/* #define _ZCGI_CONTENT_TYPE */
/* #define _ZCGI_GATEWAY_INTERFACE */
/* #define _ZCGI_HTTP_ACCEPT */
#define _ZCGI_HTTP_REFERER
#define _ZCGI_HTTP_USER_AGENT
#define _ZCGI_PATH_INFO
#define _ZCGI_PATH_TRANSLATED
#define _ZCGI_REMOTE_ADDR
#define _ZCGI_REMOTE_HOST
/* #define _ZCGI_REMOTE_IDENT */
#define _ZCGI_REMOTE_USER
#define _ZCGI_SCRIPT_FILENAME
#define _ZCGI_SCRIPT_NAME
/* #define _ZCGI_SERVER_NAME */
/* #define _ZCGI_SERVER_PORT */
/* #define _ZCGI_SERVER_PROTOCOL */
/* #define _ZCGI_SERVER_SOFTWARE */

/***************************************************************************/
/*                                                                         */
/*  Constants                                                              */
/*                                                                         */
/***************************************************************************/

#define ZMAX_FILE_NAME_SIZE            1024
#define ZMAX_STRING_SIZE               1024

/***************************************************************************/
/*                                                                         */
/*  Libraries                                                              */
/*                                                                         */
/***************************************************************************/

/* Использовать ли проекции файлов (если ОС их поддерживает) */
#define USE_MMAP

/* Использовать ли z-библиотеку */
#define USE_ZLIB

/***************************************************************************/
/*                                                                         */
/*  Checks                                                                 */
/*                                                                         */
/***************************************************************************/

/* #define ZDEBUG */

#ifdef __MSDOS__
#define ZCHECK
#endif

/* Следить ли за тем, чтобы вся аллокированная память была высвобождена */
#ifdef ZCHECK
#define ZCHECK_MEMORY_ALLOCATIONS
#endif

/* Проверять ли целостность кучи при занятии и высвобождении памяти, если
   система позволяет проверять эту самую кучу */
#ifdef ZCHECK
#define ZCHECK_SYSTEM_ALLOCATIONS
#endif

/* Проверять ли правильность обращения к элементам коллекций */
#ifdef ZCHECK
#define ZCHECK_COLLECTIONS
#endif

/* Следить ли за корректностью передаваемых параметров при вызове подпрограмм */
#ifdef ZCHECK
#define ZCHECK_PARAMS
#endif

/* Проверять ли правильность применения каких-либо алгоритмов */
#ifdef ZCHECK
#define ZCHECK_ALGORITHM
#endif

#ifdef ZCHECK_ALGORITHM
#define ZCHECK_ALGR(cnt,x,ac) \
    do                        \
    {                         \
      if( !(x) )              \
      {                       \
        (cnt)->errorIntParam = __LINE__; \
        (cnt)->printError( (cnt), zerInternalError, __FILE__); \
        ac ;                  \
      }                       \
    } while( 0 )
#define ZCHECK_ALGO(ac) ac
#else
#define ZCHECK_ALGR(cnt,x,rv)
#define ZCHECK_ALGO(ac)
#endif

#endif

#ifndef __ZALLOC_A
#define __ZALLOC_A

#ifndef __ZDEFS_A
#endif

#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif

#define ZNEW(cnt,x) (x *) zMalloc( cnt, sizeof( x ))
#define _ZFREE(cnt,x) if( (x) != NULL ) zFree( cnt, (x))
#define ZFREE(cnt,x); if( (x) != NULL ){ zFree( cnt, (x)); (x) = NULL; }

ZEXT(const char * const) zDummyString;

/* zMalloc, zRealloc & zFree */
#if defined( ZCHECK_SYSTEM_ALLOCATIONS )
ZAPI(void *) zchkMalloc( struct zcontext_t *cnt, size_t size,
    char *fileName, int lineNumber);
#define zMalloc(x,y) zchkMalloc( (x), (y), __FILE__, __LINE__)
ZAPI(void *) zchkRealloc( struct zcontext_t *cnt, void *ptr, size_t size,
    char *fileName, int lineNumber);
#define zRealloc(x,y,z) zchkRealloc( (x), (y), (z), __FILE__, __LINE__)
ZAPI(void) zchkFree( struct zcontext_t *cnt, const void *ptr,
    char *fileName, int lineNumber);
#define zFree(x,y) zchkFree( (x), (y), __FILE__, __LINE__)
#else
ZAPI(void *) zMalloc( struct zcontext_t *cnt, size_t size);
#define zchkMalloc(x,y,f,l) zMalloc( (x), (y))
ZAPI(void *) zRealloc( struct zcontext_t *cnt, void *ptr, size_t size);
#define zchkRealloc(x,y,z,f,l) zRealloc( (x), (y), (z))
ZAPI(void) zFree( struct zcontext_t *cnt, const void *ptr);
#define zchkFree(x,y,f,l) zFree( (x), (y))
#endif

/* zCalloc, zRecalloc */
#if defined( ZCHECK_SYSTEM_ALLOCATIONS )
void *zchkCalloc( struct zcontext_t *cnt, unsigned int nmemb, size_t size, Boolean zero,
    char *fileName, int lineNumber);
#define zCalloc(x,y,z,b) zchkCalloc( (x), (y), (z), (b), __FILE__, __LINE__)
void *zchkRecalloc( struct zcontext_t *cnt, void *ptr, unsigned int nmemb, size_t size,
    char *fileName, int lineNumber);
#define zRecalloc(x,y,z) zchkRecalloc( (x), (y), (z), __FILE__, __LINE__)
#else
void *zCalloc( struct zcontext_t *cnt, unsigned int nmemb, size_t size, Boolean zero);
#define zchkCalloc(x,y,z,b,f,l) zCalloc( (x), (y), (z), (b))
void *zRecalloc( struct zcontext_t *cnt, void *ptr, unsigned int nmemb, size_t size);
#define zchkRecalloc(x,y,z,f,l) zRecalloc( (x), (y), (z))
#endif

/* zStrdup, zMemdup */
#if defined( ZCHECK_SYSTEM_ALLOCATIONS )
ZAPI(char *) zchkStrdup( struct zcontext_t *cnt, const char *s,
    char *fileName, int lineNumber);
#define zStrdup(x,y) zchkStrdup( (x), (y), __FILE__, __LINE__)
ZAPI(char *) zchkStrndup( struct zcontext_t *cnt, const char *s, unsigned int length,
    char *fileName, int lineNumber);
#define zStrndup(x,y,z) zchkStrndup( (x), (y), (z), __FILE__, __LINE__)
ZAPI(void *) zchkMemdup( struct zcontext_t *cnt, const void *m, unsigned int length,
    char *fileName, int lineNumber);
#define zMemdup(x,y,z) zchkMemdup( (x), (y), (z), __FILE__, __LINE__)
#else
ZAPI(char *) zStrdup( struct zcontext_t *cnt, const char *s);
#define zchkStrdup(x,y,f,l) zStrdup( (x), (y))
ZAPI(char *) zStrndup( struct zcontext_t *cnt, const char *s, unsigned int length);
#define zchkStrndup(x,y,z,f,l) zStrndup( (x), (y), (z))
ZAPI(void *) zMemdup( struct zcontext_t *cnt, const void *m, unsigned int length);
#define zchkMemdup(x,y,z,f,l) zMemdup( (x), (y), (z))
#endif

/* zStrdupEx, zSubStrdup */
#if defined( ZCHECK_SYSTEM_ALLOCATIONS )
ZAPI(char *) zchkStrdupEx( struct zcontext_t *cnt, const char *string, const char *adds, unsigned int addsSize,
    char *fileName, int lineNumber);
#define zStrdupEx(x,y,z,s) zchkStrdupEx( (x), (y), (z), (s), __FILE__, __LINE__)
ZAPI(char *) zchkSubStrdup( struct zcontext_t *cnt, const char *begin, const char *end,
    char *fileName, int lineNumber);
#define zSubStrdup(x,y,z) zchkSubStrdup( (x), (y), (z), __FILE__, __LINE__)
#else
ZAPI(char *) zStrdupEx( struct zcontext_t *cnt, const char *string, const char *adds, unsigned int addsSize);
#define zchkStrdupEx(x,y,z,s,f,l) zStrdupEx( (x), (y), (z), (s))
ZAPI(char *) zSubStrdup( struct zcontext_t *cnt, const char *begin, const char *end);
#define zchkSubStdup(x,y,z,f,l) zSubStrdup( (x), (y), (z))
#endif

#ifdef __cplusplus
}
#endif

#endif

#ifndef __ZCHARS_A
#define __ZCHARS_A

#ifndef __ZDEFS_A
#endif

#ifdef __cplusplus
extern "C" {
#endif

#ifdef RUSSIAN_SUPPORT
#define _UPPER_RUSSIANS                "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"
#define _LOWER_RUSSIANS                "абвгдежзийклмнопрстуфхцчшщъыьэюя"
#define _VOVEL_RUSSIANS                "АЕИЙОУЫЭЮЯаеийоуыэюя"
#define _CONSONANT_RUSSIANS            "БВГДЖЗКЛМНПРСТФХЦЧШЩЪЬбвгджзклмнпрстфхцчшщъь"
#define _RUSSIAN_CAPITAL_IO            'Ё'
#define _RUSSIAN_SMALL_IO              'ё'
#define _RUSSIAN_CAPITAL_E             'Е'
#define _RUSSIAN_SMALL_E               'е'
#define _RUSSIAN_CAPITAL_SI            'Й'
#define _RUSSIAN_SMALL_SI              'й'
#define _RUSSIAN_CAPITAL_U             'У'
#define _RUSSIAN_SMALL_U               'у'
#ifdef UKRAINIAN_SUPPORT
#define WIN_UKRAINIAN_CAPITAL_IE       0xaa
#define WIN_UKRAINIAN_SMALL_IE         0xba
#define WIN_UKRAINIAN_CAPITAL_BUI      0xb2
#define WIN_UKRAINIAN_SMALL_BUI        0xb3
#define WIN_UKRAINIAN_CAPITAL_YI       0xaf
#define WIN_UKRAINIAN_SMALL_YI         0xbf
#define WIN_UKRAINIAN_CAPITAL_SU       0xa1
#define WIN_UKRAINIAN_SMALL_SU         0xa2
#define WIN_UKRAINIAN_CAPITAL_UGHE     0xa5
#define WIN_UKRAINIAN_SMALL_UGHE       0xb4
#endif
#endif

#define CHAR_ENGLISH_UP                __ZINT(0x0001u)
#define CHAR_ENGLISH_DOWN              __ZINT(0x0002u)
#define CHAR_ENGLISH_VOWEL             __ZINT(0x0004u)
#define CHAR_ENGLISH_CONSONANT         __ZINT(0x0008u)
#define CHAR_RUSSIAN_UP                __ZINT(0x0010u)
#define CHAR_RUSSIAN_DOWN              __ZINT(0x0020u)
#define CHAR_RUSSIAN_VOWEL             __ZINT(0x0040u)
#define CHAR_RUSSIAN_CONSONANT         __ZINT(0x0080u)
#define CHAR_DIGIT                     __ZINT(0x0100u)
#define CHAR_XDIGIT                    __ZINT(0x0200u)
#define CHAR_SPACE                     __ZINT(0x0400u)
#define CHAR_INLINE_SPACE              __ZINT(0x0800u)
#define CHAR_CONTROL                   __ZINT(0x1000u)
#define CHAR_PUNCT                     __ZINT(0x2000u)
#define CHAR_SPECIAL                   __ZINT(0x4000u)
#define CHAR_URLSPEC                   __ZINT(0x8000u)
#define CHAR_USER_DEFINED              __ZINT(0x10000u)

#define CHAR_ENGLISH            (CHAR_ENGLISH_UP | CHAR_ENGLISH_DOWN)
#define CHAR_RUSSIAN            (CHAR_RUSSIAN_UP | CHAR_RUSSIAN_DOWN)
#define CHAR_ALPHA              CHAR_ENGLISH
#define CHAR_ALNUM              (CHAR_DIGIT | CHAR_ALPHA)
#define CHAR_UPPER              CHAR_ENGLISH_UP
#define CHAR_LOWER              CHAR_ENGLISH_DOWN
#define CHAR_VOWEL              (CHAR_ENGLISH_VOWEL | CHAR_RUSSIAN_VOWEL)
#define CHAR_CONSONANT          (CHAR_ENGLISH_CONSONANT | CHAR_RUSSIAN_CONSONANT)

ZEXT(unsigned zint_t) ztCharbitTable[256];

#define _testChar(x,y)          (ztCharbitTable[ (x) ] & (y))
#define _setCharbit(x,y)        (ztCharbitTable[ (x) ] |= (y))
#define _unsetCharbit(x,y)      (ztCharbitTable[ (x) ] &= ~(y))

#define testChar(x,y)           _testChar( (x) & 0xff, y)
#define setCharbit(x,y)         _setCharbit( (x) & 0xff, y)
#define unsetCharbit(x,y)       _unsetCharbit( (x) & 0xff, y)

#define _isSpace(x)             (ztCharbitTable[ (x) ] & CHAR_SPACE)
#define _isInlineSpace(x)       (ztCharbitTable[ (x) ] & CHAR_INLINE_SPACE)
#define _isAlpha(x)             (ztCharbitTable[ (x) ] & CHAR_ALPHA)
#define _isUpper(x)             (ztCharbitTable[ (x) ] & CHAR_UPPER)
#define _isLower(x)             (ztCharbitTable[ (x) ] & CHAR_LOWER)
#define _isAlnum(x)             (ztCharbitTable[ (x) ] & CHAR_ALNUM)
#define _isDigit(x)             (ztCharbitTable[ (x) ] & CHAR_DIGIT)
#define _isXDigit(x)            (ztCharbitTable[ (x) ] & CHAR_XDIGIT)
#define _isPunct(x)             (ztCharbitTable[ (x) ] & CHAR_PUNCT) 
#define _isSpecial(x)           (ztCharbitTable[ (x) ] & CHAR_SPECIAL)
#define _isURLSpecial(x)        (ztCharbitTable[ (x) ] & CHAR_URLSPEC)
#define _isRussian(x)           (ztCharbitTable[ (x) ] & CHAR_RUSSIAN)
#define _isVowel(x)             (ztCharbitTable[ (x) ] & CHAR_VOWEL) 
#define _isConsonant(x)         (ztCharbitTable[ (x) ] & CHAR_CONSONANT)

#define isSpace(x)              _isSpace( (x) & 0xff )
#define isInlineSpace(x)        _isInlineSpace( (x) & 0xff )
#define isAlpha(x)              _isAlpha( (x) & 0xff )
#define isUpper(x)              _isUpper( (x) & 0xff )
#define isLower(x)              _isLower( (x) & 0xff )
#define isAlnum(x)              _isAlnum( (x) & 0xff )
#define isDigit(x)              _isDigit( (x) & 0xff )
#define isXDigit(x)             _isXDigit( (x) & 0xff )
#define isPunct(x)              _isPunct( (x) & 0xff )
#define isSpecial(x)            _isSpecial( (x) & 0xff )
#define isURLSpecial(x)         _isURLSpecial( (x) & 0xff )
#define isRussian(x)            _isRussian( (x) & 0xff )
#define isVowel(x)              _isVowel( (x) & 0xff )
#define isConsonant(x)          _isConsonant( (x) & 0xff )

#define _isAscii(x)             (((x) & 0x80) == 0)
#define isAscii(x)              _isAscii(x)

ZEXT(unsigned char) ztLowerTable[256];
ZEXT(unsigned char) ztUpperTable[256];
#define _toLower(x)             ztLowerTable[(x)]
#define _toUpper(x)             ztUpperTable[(x)]
#define toLower(x)              _toLower( (x) & 0xff )
#define toUpper(x)              _toUpper( (x) & 0xff )

/* Cyryllic support */
#ifdef RUSSIAN_SUPPORT
ZEXT(unsigned char) ztSequenceTable[256];
ZEXT(unsigned char) ztFixupTable[256];

ZEXT(const char *) zsUpperRussians;
ZEXT(const char *) zsLowerRussians;
ZEXT(const char *) zsVowelRussians;
ZEXT(const char *) zsConsonantRussians;

void zInitRussians( void );
#endif

#ifdef __cplusplus
}
#endif

#endif

#ifndef __ZLIB_A
#define __ZLIB_A

#ifndef __ZDEFS_A
#endif

#ifndef ___PSTDIO_A
#endif

#ifdef __cplusplus
extern "C" {
#endif

struct zcontext_t
{
/* Errors */
  unsigned zint_t errorCode;
  const char * const *errorFormats;
  const char *errorPtr;
  int errorIntParam;
  int errorIntParam2;
  const char *errorStrParam;
  const char *errorStrParam2;
  zprinterror_t printError;
  zprinterror_t printErr;

/* Memory allocation & collections */
  int allocCount;
  zmemfail_t allocFail;
  int lastStringSize;
  unsigned int lastCollectionIndex;
  Boolean lastDuplicate;
#if defined( __MSVC__ )
  unsigned long hHeap;
#endif

/* I/O */
  unsigned int ioFlags;
  unsigned int ioDirection;
  int localCharset;
  int remoteCharset;
  int remoteStrictCharset;
  char *convTable;           /* remote -> local */
  char *recodeTable;         /* local -> remote */
  char *recodeStrictTable;   /* local -> remote */
  FILE *input;
  FILE *output;
  struct zstrbuf_t *ioStrbuf;
  zwrite_t ioWrite;
  zflush_t ioFlush;

/* zvprintf's */
  char *ioBuf;
  int ioBufSize;
  int ioBufLength;

/* Config */
  Boolean confSuccess;
  int confLineNumber;
  int confSectionLineNumber;
  struct zconfsec_t *confSection;
  unsigned int confAreaFlags;
  const char *confName;
  const unsigned zint_t *confErrors;
  zprocessstring_t processConfigString;

/* File operations */
  zint_t tmpFileNumber;
  zint_t tmpFileMaxCount;
  Boolean tmpFileSuccess;
  Boolean rewriteTextMode;
  Boolean tempFileTextMode;

/* Inet data */
  int inetError;
  int inetErrorArea;
  Boolean inetStarted;
  Boolean inetDebug;

/* Debug */
  unsigned zint_t debugArea;
  int debugLevel;
  unsigned int debugProgLevel;
  FILE *debugStream;

/* Application's */
  Boolean success;
  char *nextItem;
  unsigned int runFlags;
  unsigned int patternFlags;
  int verboseLevel;
  struct zcgidata_t *cgiData;
  int timeArea;
  int language;

/* Heaps */
  void *heap1;
  void *heap2;
  void *heap3;

/* Internal info */
  void *info1;
  void *info2;
  void *info3;

/* User data */
  void *userData;
  void *userData2;
  void *userData3;
};

/* #define ZCONTEXT_IOFLAG_CHARSET_PROCESSED        0x0001u */
#define ZCONTEXT_IOFLAG_CHARSET_CONV             0x0002u
#define ZCONTEXT_IOFLAG_CHARSET_RECODE           0x0004u
#define ZCONTEXT_IOFLAG_CHARSET_RECODE_STRICT    0x0008u
#define ZCONTEXT_IOFLAG_STRICT_VALUE             0x0010u
#define ZCONTEXT_IOFLAG_AUTOFLUSH                0x0020u
#define ZCONTEXT_IOFLAG_INTERNAL_BUFFER          0x0040u
#define ZCONTEXT_IOFLAG_NO_INTERNAL_BUFFER       0x0080u

#define ZCONTEXT_RUNFLAG_VERBOSE                 0x0001u
#define ZCONTEXT_RUNFLAG_SYMLINKS                0x0002u
#define ZCONTEXT_RUNFLAG_RECURSIVE               0x0004u
#define ZCONTEXT_RUNFLAG_QUIET                   0x0008u
#define ZCONTEXT_RUNFLAG_FULL_FILE_NAMES         0x0010u

#define zConvTable(cnt) \
    (zCheckFlags( (cnt)->ioFlags, ZCONTEXT_IOFLAG_CHARSET_CONV) ? (cnt)->confTable : NULL)
#define zRecodeTable(cnt) \
    (zCheckFlags( (cnt)->ioFlags, ZCONTEXT_IOFLAG_CHARSET_RECODE) ? (cnt)->recodeTable : NULL)
#define zRecodeStrictTable(cnt) \
    (zCheckFlags( (cnt)->ioFlags, ZCONTEXT_IOFLAG_CHARSET_RECODE_STRICT) ? (cnt)->recodeStrictTable : NULL)

#define zciCreateHeap                  0x0001u
#define zciHeapSerialize               0x0002u

ZAPI(Boolean) zContextInit( struct zcontext_t *cnt, zprinterror_t printError,
    const char * const *errorFormats, zmemfail_t memFail, unsigned int flags);
ZAPI(void) zContextCopy( struct zcontext_t *dest, struct zcontext_t *src);
ZAPI(void) zContextFree( struct zcontext_t *cnt );

enum
{
  zlnEnglish,
#if defined( RUSSIAN_SUPPORT )
  zlnRussian,
#endif
#if defined( RUSSIAN_SUPPORT ) && defined( UKRAINIAN_SUPPORT )
  zlnUkrainian,
#endif
};

enum
{
  ztaNone = 0,
  ztaYear,
  ztaMonth,
  ztaDay,
  ztaHour,
  ztaMinute,
  ztaSecond
};

#ifdef __cplusplus
}
#endif

#endif

#ifndef __ZERROR_A
#define __ZERROR_A

#ifndef __ZDEFS_A
#endif

#ifdef __cplusplus
extern "C" {
#endif

#define ZERROR_COPY(dst,src) \
  do                         \
  {                          \
    (dst)->errorCode = (src)->errorCode; \
    (dst)->errorPtr = (src)->errorPtr; \
    (dst)->errorIntParam = (src)->errorIntParam; \
    (dst)->errorIntParam2 = (src)->errorIntParam2; \
    (dst)->errorStrParam = (src)->errorStrParam; \
    (dst)->errorStrParam2 = (src)->errorStrParam2; \
  } while( 0 )

void zDefaultPrintError( struct zcontext_t *cnt, unsigned zint_t errorCode, const char *name);
ZAPI(void) zSetErrorHandler( struct zcontext_t *cnt, zprinterror_t handler);

#define zefCodeMask                    __ZINT(0x0000ffffu)
#define zefGeneral                     __ZINT(0x00010000u)
#define zefSystem                      __ZINT(0x00020000u)
#define zefWarning                     __ZINT(0x00040000u)
#define zefSpecial                     __ZINT(0x00080000u)
#define zefDebug                       __ZINT(0x00100000u)
#define zefNoHeader                    __ZINT(0x00200000u)
#define zefCGI                         __ZINT(0x01000000u)
#define zefAccount                     __ZINT(0x02000000u)
#define zefDatabase                    __ZINT(0x04000000u)
#define zefUser1                       __ZINT(0x10000000u)
#define zefUser2                       __ZINT(0x20000000u)
#define zefUser3                       __ZINT(0x40000000u)
#define zefUser4                       __ZINT(0x80000000u)

#define _zErrorCode(x)                 ((int) ((x) & zefCodeMask))

enum
{
  zecNone = 0,
  zecInetArea,
  zecInternalError,
  zecExternalError,
  zecInvalidValue,
  zecValueRange,
  zecSameValue,
  zecNotInited,
  zecNotSupported,
  zecNoMemory,
  zecSystemTime,
  zecTimeValue,
  zecTimeString,
  zecUnknownCharset,
  zecBufferLimit,
  zecInvalidStringFormat,
  zecDataError,
  zecProcCreate,
  zecTempFileName,
  zecZeroLengthFile,
  zecUnexpectedFileEnd,
  zecFileFormat,
  zecFileId,
  zecFileSize,
  zecFileLength,
  zecFileOpen,
  zecFileTell,
  zecFileSeek,
  zecFileStat,
  zecFileLock,
  zecFileRead,
  zecFileWrite,
  zecFileRename,
  zecFileAccess,
  zecFileExist,
  zecFileMmap,
  zecFileDup,
  zecTempFileFormat,
  zecTempFileOpen,
  zecTempFileTell,
  zecTempFileSeek,
  zecTempFileStat,
  zecTempFileRead,
  zecTempFileWrite,
  zecTempFileRename,
  zecTempDirNotExist,
  zecTempDirRights,
  zecTempDirIsntDir,
  zecPipeCreate,
  zecDirCreate,
  zecDirOpen,
  zecNotDirectory,
  zecNotRegularFile,
  zecInvalidPattern,
  zecConfFileOpen,
  zecConfInvalidStringFormat,
  zecConfUnknownSection,
  zecConfUnknownKeyword,
  zecConfInvalidValue,
  zecNeedRecursive,
  zecLastError,
  zecDBFSize = 100,
  zecDBFFieldCount,
  zecDBFFieldSize,
  zecDBFUnknownFieldType,
  zecDBFId,
  zecDBFEntrySize,
  zecDBFInvalidEntrySize,
  zecDBFInvalidEntryCount,
  zecDBFInvalidHeaderSize,
  zecDBFCommentFileSize,
  zecDBFBlockCount,
  zecDBFBlockSize,
  zecDBFNoSuchField,
  zecLast = 200
};

#define zerNone                        zecNone
#define zerInetArea                    (zefGeneral | zecInetArea)
#define zerInternalError               (zefGeneral | zecInternalError)
#define zerExternalError               (zefGeneral | zecExternalError)
#define zerInvalidValue                (zefGeneral | zecInvalidValue)
#define zerValueRange                  (zefGeneral | zecValueRange)
#define zerSameValue                   (zefGeneral | zecSameValue)
#define zerNotInited                   (zefGeneral | zecNotInited)
#define zerNotSupported                (zefGeneral | zecNotSupported)
#define zerNoMemory                    (zefGeneral | zecNoMemory)
#define zerSystemTime                  (zefGeneral | zecSystemTime)
#define zerTimeValue                   (zefGeneral | zecTimeValue)
#define zerTimeString                  (zefGeneral | zecTimeString)
#define zerUnknownCharset              (zefGeneral | zecUnknownCharset)
#define zerBufferLimit                 (zefGeneral | zecBufferLimit)
#define zerInvalidStringFormat         (zefGeneral | zecInvalidStringFormat)
#define zerDataError                   (zefGeneral | zecDataError)
#define zerProcCreate                  (zefGeneral | zecProcCreate)
#define zerTempFileName                (zefGeneral | zecTempFileName)
#define zerZeroLengthFile              (zefGeneral | zecZeroLengthFile)
#define zerUnexpectedFileEnd           (zefGeneral | zecUnexpectedFileEnd)
#define zerFileFormat                  (zefGeneral | zecFileFormat)
#define zerFileId                      (zefGeneral | zecFileId)
#define zerFileSize                    (zefGeneral | zecFileSize)
#define zerFileLength                  (zefGeneral | zecFileLength)
#define zerFileOpen                    (zefGeneral | zecFileOpen)
#define zerFileTell                    (zefGeneral | zecFileTell)
#define zerFileSeek                    (zefGeneral | zecFileSeek)
#define zerFileStat                    (zefGeneral | zecFileStat)
#define zerFileLock                    (zefGeneral | zecFileLock)
#define zerFileRead                    (zefGeneral | zecFileRead)
#define zerFileWrite                   (zefGeneral | zecFileWrite)
#define zerFileRename                  (zefGeneral | zecFileRename)
#define zerFileAccess                  (zefGeneral | zecFileAccess)
#define zerFileExist                   (zefGeneral | zecFileExist)
#define zerFileMmap                    (zefGeneral | zecFileMmap)
#define zerFileDup                     (zefGeneral | zecFileDup)
#define zerTempFileFormat              (zefGeneral | zecTempFileFormat)
#define zerTempFileOpen                (zefGeneral | zecTempFileOpen)
#define zerTempFileTell                (zefGeneral | zecTempFileTell)
#define zerTempFileSeek                (zefGeneral | zecTempFileSeek)
#define zerTempFileStat                (zefGeneral | zecTempFileStat)
#define zerTempFileRead                (zefGeneral | zecTempFileRead)
#define zerTempFileWrite               (zefGeneral | zecTempFileWrite)
#define zerTempFileRename              (zefGeneral | zecTempFileRename)
#define zerTempDirNotExist             (zefGeneral | zecTempDirNotExist)
#define zerTempDirRights               (zefGeneral | zecTempDirRights)
#define zerTempDirIsntDir              (zefGeneral | zecTempDirIsntDir)
#define zerPipeCreate                  (zefGeneral | zecPipeCreate)
#define zerDirCreate                   (zefGeneral | zecDirCreate)
#define zerDirOpen                     (zefGeneral | zecDirOpen)
#define zerNotDirectory                (zefGeneral | zecNotDirectory)
#define zerNotRegularFile              (zefGeneral | zecNotRegularFile)
#define zerInvalidPattern              (zefGeneral | zecInvalidPattern)
#define zerConfFileOpen                (zefGeneral | zecConfFileOpen)
#define zerConfInvalidStringFormat     (zefGeneral | zecConfInvalidStringFormat)
#define zerConfUnknownSection          (zefGeneral | zecConfUnknownSection)
#define zerConfUnknownKeyword          (zefGeneral | zecConfUnknownKeyword)
#define zerConfInvalidValue            (zefGeneral | zecConfInvalidValue)
#define zerNeedRecursive               (zefGeneral | zecNeedRecursive)
#define zerDBFSize                     (zefGeneral | zecDBFSize)
#define zerDBFFieldCount               (zefGeneral | zecDBFFieldCount)
#define zerDBFFieldSize                (zefGeneral | zecDBFFieldSize)
#define zerDBFUnknownFieldType         (zefGeneral | zecDBFUnknownFieldType)
#define zerDBFId                       (zefGeneral | zecDBFId)
#define zerDBFEntrySize                (zefGeneral | zecDBFEntrySize)
#define zerDBFInvalidEntrySize         (zefGeneral | zecDBFInvalidEntrySize)
#define zerDBFInvalidEntryCount        (zefGeneral | zecDBFInvalidEntryCount)
#define zerDBFInvalidHeaderSize        (zefGeneral | zecDBFInvalidHeaderSize)
#define zerDBFCommentFileSize          (zefGeneral | zecDBFCommentFileSize)
#define zerDBFBlockCount               (zefGeneral | zecDBFBlockCount)
#define zerDBFBlockSize                (zefGeneral | zecDBFBlockSize)
#define zerDBFNoSuchField              (zefGeneral | zecDBFNoSuchField)
#define zerLast                        zecLast

ZAPI(char *) zSystemErrorString( unsigned zint_t errorCode, char *buf, int size);

ZEXT(const char * const) zErrorEnglishFormats[zecLastError+1];
#if defined( RUSSIAN_SUPPORT )
ZEXT(const char * const) zErrorRussianFormats[zecLastError+1];
#endif
#if defined( RUSSIAN_SUPPORT ) && defined( UKRAINIAN_SUPPORT )
ZEXT(const char * const) zErrorUkrainianFormats[zecLastError+1];
#endif

ZAPI(char *) zGetErrorString( struct zcontext_t *cnt, char *buffer, int size,
     unsigned zint_t errorCode, const char *name);

#ifdef __cplusplus
}
#endif

#endif

#ifndef ___PSTDIO_A
#define ___PSTDIO_A

#ifndef __ZDEFS_A
#endif

#include <stdio.h>

#ifndef STDIN_FILENO
#define STDIN_FILENO                   0
#define STDOUT_FILENO                  1
#define STDERR_FILENO                  2
#endif

#ifdef HAVE_SNPRINTF
#define SPRINTF(x,y) snprintf(x,y,
#else
#define SPRINTF(x,y) sprintf(x,
#endif

#endif

#ifndef __ZSTDIO_A
#define __ZSTDIO_A

#ifndef __ZDEFS_A
#endif

#ifndef ___PSTDIO_A
#endif

#include <stdarg.h>

#ifdef __cplusplus
extern "C" {
#endif

enum
{
  zioDirectionStream = 0,
  zioDirectionStrbuf,
  zioDirectionFunction
};

/* Простая копия раздела IO из zcontext_t */
struct zioinfo_t
{
  unsigned int ioFlags;
  unsigned int ioDirection;
  int localCharset;
  int remoteCharset;
  int remoteStrictCharset;
  char *convTable;           /* remote -> local */
  char *recodeTable;         /* local -> remote */
  char *recodeStrictTable;   /* local -> remote */
  FILE *input;
  FILE *output;
  struct zstrbuf_t *ioStrbuf;
  zwrite_t ioWrite;
  zflush_t ioFlush;
};

#define ZIO_SAVE(d,s) \
  do                  \
  {                   \
    (d)->ioFlags = (s)->ioFlags; \
    (d)->ioDirection = (s)->ioDirection; \
    (d)->localCharset = (s)->localCharset; \
    (d)->remoteCharset = (s)->remoteCharset; \
    (d)->remoteStrictCharset = (s)->remoteStrictCharset; \
    (d)->convTable = (s)->convTable; \
    (d)->recodeTable = (s)->recodeTable; \
    (d)->recodeStrictTable = (s)->recodeStrictTable; \
    (d)->input = (s)->input; \
    (d)->output = (s)->output; \
    (d)->ioStrbuf = (s)->ioStrbuf; \
    (d)->ioWrite = (s)->ioWrite; \
    (d)->ioFlush = (s)->ioFlush; \
  } while( 0 )

#define ZIO_RESTORE(d,s) ZIO_SAVE(d,s)

ZAPI(void) zioSaveInfo( struct zcontext_t *cnt, struct zioinfo_t *info);
ZAPI(void) zioRestoreInfo( struct zcontext_t *cnt, struct zioinfo_t *info);

ZAPI(void) zioSetOutputStrbuf( struct zcontext_t *cnt, struct zstrbuf_t *sb, struct zioinfo_t *info);
ZAPI(void) zioSetOutputStream( struct zcontext_t *cnt, FILE *stream, struct zioinfo_t *info);
ZAPI(void) zioSetOutputFunction( struct zcontext_t *cnt, zwrite_t writeFunc, zflush_t flushFunc, struct zioinfo_t *info);

#define zpfText                     0x0001u
#define zpfStrictText               0x0002u
#define zpfValue                    0x0004u
#define zpfStrictValue              0x0008u
#define zpfEscaped                  0x0010u
#define zpfStrictEscaped            0x0020u
#define zpfUpperCase                0x0040u
#define zpfLowerCase                0x0080u
#define zpfEscapedQuote             0x0100u
#define zpfEscapedSpace             0x0200u
#define zpfBreakLine                0x0400u
#define zpfDontRecode               0x1000u
#define zpfFlush                    0x2000u
#define zpfLast                     0x8000u

ZAPI(Boolean) zflush( struct zcontext_t *cnt );
ZAPI(Boolean) zPrintData( struct zcontext_t *cnt, unsigned int flags, const char *data, int length);

ZAPI(Boolean) zvprintf( struct zcontext_t *cnt, const char *fmt, va_list args);
ZAPI(Boolean) zprintf( struct zcontext_t *cnt, const char *fmt, ...);
ZAPI(Boolean) zfprintf( struct zcontext_t *cnt, FILE *stream, const char *fmt, ...);
ZAPI(Boolean) zsprintf( char *string, int size, const char *fmt, ...);
ZAPI(Boolean) ztprintf( struct zcontext_t *cnt, char *string, int size, const char *fmt, ...);
ZAPI(char *) zaprintf( struct zcontext_t *cnt, const char *fmt, ...);
ZAPI(char *) zbprintf( struct zcontext_t *cnt, const char *fmt, ...);

#ifdef __cplusplus
}
#endif

#endif

#ifndef ___PTIME_A
#define ___PTIME_A

#ifndef __ZDEFS_A
#endif

#ifdef TIME_WITH_SYS_TIME
#  include <sys/time.h>
#  include <time.h>
#else
# ifdef HAVE_SYS_TIME_H
#  include <sys/time.h>
# else
#  include <time.h>
# endif
#endif

#define ZTIME_WRONG                ((time_t) -1)
#define ZTIME_NONE                 ((time_t) 0)

#endif

#ifndef __ZTIME_A
#define __ZTIME_A

#ifndef __ZDEFS_A
#endif

#ifndef ___PTIME_A
#endif

#if defined( HAVE_FTIME ) && !defined( HAVE_GETTIMEOFDAY )
#include <sys/timeb.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif

/* Time strings */
#define ZTIME_MONTH_JANUARY            0
#define ZTIME_MONTH_FEBRUARY           1
#define ZTIME_MONTH_MARCH              2
#define ZTIME_MONTH_APRIL              3
#define ZTIME_MONTH_MAY                4
#define ZTIME_MONTH_JUNE               5
#define ZTIME_MONTH_JULY               6
#define ZTIME_MONTH_AUGUST             7
#define ZTIME_MONTH_SEPTEMBER          8
#define ZTIME_MONTH_OCTOBER            9
#define ZTIME_MONTH_NOVEMBER           10
#define ZTIME_MONTH_DECEMBER           11

#define ZTIME_WEEKDAY_SUNDAY           0
#define ZTIME_WEEKDAY_MONDAY           1
#define ZTIME_WEEKDAY_TUESDAY          2
#define ZTIME_WEEKDAY_WEDNESDAY        3
#define ZTIME_WEEKDAY_THURSDAY         4
#define ZTIME_WEEKDAY_FRIDAY           5
#define ZTIME_WEEKDAY_SATURDAY         6

enum
{
  ztsMonthList = 0,
  ztsMonthAltList,
  ztsMonthShortList,
  ztsMonthAltShortList,
  ztsWeekdayList,
  ztsWeekdayAltList,
  ztsWeekdayShortList,
  ztsWeekdayAltShortList,
  ztsTimeFormats,
  ztsTimePeriods,
  ztsLastStrings
};

enum
{
  ztsDateFormat = 0,
  ztsDateAltFormat,
  ztsDateShortFormat,
  ztsDateAltShortFormat,
  ztsTimeFormat,
  ztsTimeAltFormat,
  ztsTimeShortFormat,
  ztsTimeAltShortFormat,
  ztsDateTimeFormat,
  ztsDateTimeAltFormat,
  ztsDateTimeShortFormat,
  ztsDateTimeAltShortFormat,
  ztsLastFormat
};

enum
{
  ztsTimePoint = 0,
  ztsTimePeriod,
  ztsStartTimePeriod,
  ztsEndTimePeriod,
  ztsLastPeriod
};

ZEXT(const char *) zMonthEnglishList[13];
ZEXT(const char *) zMonthAltEnglishList[13];
ZEXT(const char *) zMonthShortEnglishList[13];
ZEXT(const char *) zWeekdayEnglishList[8];
ZEXT(const char *) zWeekdayShortEnglishList[8];
ZEXT(const char *) zTimeEnglishFormats[ztsLastFormat+1];
ZEXT(const char *) zTimeEnglishPeriods[ztsLastPeriod+1];
ZEXT(const char **) zTimeEnglishStrings[ztsLastStrings+1];

#if defined( RUSSIAN_SUPPORT )
ZEXT(const char *) zMonthRussianList[13];
ZEXT(const char *) zMonthAltRussianList[13];
ZEXT(const char *) zMonthShortRussianList[13];
ZEXT(const char *) zWeekdayRussianList[8];
ZEXT(const char *) zWeekdayShortRussianList[8];
ZEXT(const char *) zWeekdayAltShortRussianList[8];
ZEXT(const char *) zTimeRussianFormats[ztsLastFormat+1];
ZEXT(const char *) zTimeRussianPeriods[ztsLastPeriod+1];
ZEXT(const char **) zTimeRussianStrings[ztsLastStrings+1];
#endif

#if defined( RUSSIAN_SUPPORT ) && defined( UKRAINIAN_SUPPORT )
ZEXT(const char *) zMonthUkrainianList[13];
ZEXT(const char *) zMonthAltUkrainianList[13];
ZEXT(const char *) zMonthShortUkrainianList[13];
ZEXT(const char *) zWeekdayUkrainianList[8];
ZEXT(const char *) zWeekdayShortUkrainianList[8];
ZEXT(const char *) zWeekdayAltShortUkrainianList[8];
ZEXT(const char *) zTimeUkrainianFormats[ztsLastFormat+1];
ZEXT(const char *) zTimeUkrainianPeriods[ztsLastPeriod+1];
ZEXT(const char **) zTimeUkrainianStrings[ztsLastStrings+1];
#endif

#define ZTIME_YEAR_BASE                1970
#define ZTIME_YEAR_EPOCH               1900
#define ZTIME_YEAR_MAX                 137
#define ZTIME_SECS_PER_MIN             60
#define ZTIME_MINS_PER_HOUR            60
#define ZTIME_HOUR_PER_DAY             24
#define ZTIME_SECS_PER_HOUR            (ZTIME_SECS_PER_MIN * ZTIME_MINS_PER_HOUR)
#define ZTIME_SECS_PER_DAY             (__ZINT(60) * __ZINT(60) * __ZINT(24))
#define ZTIME_DAYS_PER_WEEK            7
#define ZTIME_DAYS_PER_YEAR            365
#define ZTIME_MONT_PER_YEAR            12

ZEXT(const int) zTimeMonthDays[ZTIME_MONT_PER_YEAR+1];
ZEXT(const int) zTimeLeapDays[ZTIME_MONT_PER_YEAR+1];

#define zTimeLeapYear(y)               (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
#define zTimeLeapAddition(y)           (((y) / 4) - ((y) / 100) + ((y) / 400))
#define zTimeIsOffday(y)               (y == ZTIME_WEEKDAY_SATURDAY || y == ZTIME_WEEKDAY_SUNDAY)

time_t ztimegm( const struct tm *tm );

/* ztime_t */
typedef unsigned zint_t ztime_t;

/*
   year:   0-63 [1980-2043]
   month:  1-12
   day:    1-31
   hour:   0-23
   minute: 0-59
   second: 0-59
*/

#define ZTIME_MASK_YEAR                __ZINT(0xfc000000u)
#define ZTIME_MASK_MONTH               __ZINT(0x03c00000u)
#define ZTIME_MASK_DAY                 __ZINT(0x003e0000u)
#define ZTIME_MASK_HOUR                __ZINT(0x0001f000u)
#define ZTIME_MASK_MINUTE              __ZINT(0x00000fc0u)
#define ZTIME_MASK_SECOND              __ZINT(0x0000003fu)
#define ZTIME_MASK_DATE                __ZINT(0xfffe0000u)
#define ZTIME_MASK_TIME                __ZINT(0x0001ffffu)

#define _ZDATEV(ye,mo,da) \
    ((((((ztime_t) (da)) & 0x1f) << 1) | ((((ztime_t) (mo)) & 0x0f) << 6) | ((((ztime_t) (ye)) & 0x3f) << 10)) << 16)
#define _ZTIMEV(ho,mi,se) \
    ((((ztime_t) (se)) & 0x3f) | ((((ztime_t) (mi)) & 0x3f) << 6) | ((((ztime_t) (ho)) & 0x1f) << 12))
#define _ZTIME(ye,mo,da,ho,mi,se) \
    ((_ZDATEV((ye),(mo),(da)) & ZTIME_MASK_DATE) | (_ZTIMEV((ho),(mi),(se)) & ZTIME_MASK_TIME))

#define ZTIME_EPOCH_START              _ZTIME(0,1,1,0,0,0)
#define ZTIME_EPOCH_END                _ZTIME(0x1f,ZTIME_MONT_PER_YEAR,31,ZTIME_HOUR_PER_DAY-1,ZTIME_MINS_PER_HOUR-1,ZTIME_SECS_PER_MIN-1);

#define zTimeYear(t)                   ((int) ((((t) >> 26) & 0x3f) + 80))
#define zTimeMonth(t)                  ((int) (((t) >> 22) & 0x0f))
#define zTimeDay(t)                    ((int) (((t) >> 17) & 0x1f))
#define zTimeHour(t)                   ((int) (((t) >> 12) & 0x1f))
#define zTimeMinute(t)                 ((int) (((t) >> 6) & 0x3f))
#define zTimeSecond(t)                 ((int) ((t) & 0x3f))
#define zTimeDate(t)                   (((ztime_t) (t)) & ZTIME_MASK_DATE)
#define zTimeTime(t)                   (((ztime_t) (t)) & ZTIME_MASK_TIME)

#define ztfGlobalTime                  0x0001u
#define ztfStandardTime                0x0002u
#define ztfDaylightTime                0x0004u
#define ztfNoTime                      0x0008u
#define ztfAsIs                        0x0010u
#define ztfSunday                      0x0020u

ZAPI(ztime_t) zTime( time_t t, unsigned int flags);
ZAPI(ztime_t) zCurrentTime( unsigned int flags );
ZAPI(time_t) zNormalTime( ztime_t zt, struct tm *ptm, unsigned int flags);
ZAPI(struct tm *) zMakeTime( ztime_t zt, struct tm *ptm, unsigned int flags);
ZAPI(int) zTimeWeekday( ztime_t zt, unsigned int flags);

/* Time transform */
zint_t zTimeYearStart( ztime_t date );
zint_t zTimeYearEnd( ztime_t date );

zint_t zTimeMonthStart( ztime_t date );
zint_t zTimeMonthEnd( ztime_t date );

zint_t zTimeDayStart( ztime_t date );
zint_t zTimeDayEnd( ztime_t date );

zint_t zTimePrevMonth( zint_t date );
zint_t zTimeNextMonth( zint_t date );

zint_t zTimePrevDay( zint_t date );
zint_t zTimeNextDay( zint_t date );

ztime_t zTimePrevHour( zint_t date );
ztime_t zTimeNextHour( zint_t date );

int zTimeDayCount( ztime_t startDate, ztime_t endDate);

/* Time string */
ZAPI(int) zTimeString( char *buf, int size, const char *fmt, struct tm *tm, const char ***strings);
ZAPI(char *) zTimeFormat( char *buf, int size, const char *fmt, struct tm *tm, const char ***strings);

#define ztsDayFirst                    0x0001u
#define ztsRussianNames                0x0002u

ZAPI(ztime_t) zTimeFromString( const char *string, char **rv, unsigned int flags);

/* Time value */
#if defined( HAVE_GETTIMEOFDAY ) && defined( __MSVC__ )
struct unix_timeval
{
  long tv_sec;           /* seconds */
  long tv_usec;          /* and microseconds */
};
#endif

enum
{
  ettUnknown,
  ettTime,
  ettTimeValue
};

struct ztimeval_t
{
  int type;
#if defined( HAVE_GETTIMEOFDAY )
#if defined( __MSVC__ )
  struct unix_timeval tv;
#else
  struct timeval tv;
#endif
#elif defined( HAVE_FTIME )
  struct timeb tv;
#else
  time_t tv;
#endif
};

ZAPI(Boolean) zInitTimeValue( struct ztimeval_t *t );
ZAPI(Boolean) zSubTimeValue( struct ztimeval_t *t2, struct ztimeval_t *t1, int *psecs, int *pmsecs);
ZAPI(char *) zGetTimeValue( char *buf, int size, struct ztimeval_t *t2, struct ztimeval_t *t1);

/* Time Number */
zint_t zGetTimeNumber( zint_t delta );

#ifdef __cplusplus
}
#endif

#endif

#ifndef __CFG_A
#define __CFG_A

#ifndef __ZCFG_A
#endif

/***************************************************************************/
/*                                                                         */
/*  Global options                                                         */
/*                                                                         */
/***************************************************************************/

/* Whether to support Russian or not */
#define RUSSIAN_RELEASE

/* The minimum length of a word in the index. */
#define MIN_WORD_LENGTH                1

/* The maximum length of a word in the index. */
#define MAX_WORD_LENGTH                32

/* The default name of the index file in case it is not specified
   in the command line (for flindex, flsearch and fldump). */
#define DEFAULT_INDEX_FILE_NAME        "index.flu"

/* This value may be 0, 1, 2 or 3. */
#define DEFAULT_VERBOSE_LEVEL          2

/* Access permisions for the index file.
   If you don't want to set the permisions comment it out. */
/* #define INDEX_PERMISIONS               0444 */

#define MAX_NAME_LENGTH                1024
#define MAX_TITLE_LENGTH               160
#define MAX_CONTENT_LENGTH             512

/***************************************************************************/
/*                                                                         */
/*  Indexing options                                                       */
/*                                                                         */
/***************************************************************************/

#define MAX_SWAP_FILES                 10

#define MAX_MEMORY_VOLUM               __ZINT(5000000)

#define IGNORE_FILES_LIMIT             512
#define IGNORE_PERCENT_LIMIT           101

/* This is how many bytes deep FLUIdS will look into an HTML file to
   attempt to find a ContentType <META> tag. */
#define CHARSET_META_TAG_BYTES         (2*1024)

/* Default content type for a file.
   Should be one of CTYPE_NONTEXT, CTYPE_TEXT, CTYPE_HTML or CTYPE_UNKNOWN. */
#define DEFAULT_CONTENT_TYPE           CTYPE_UNKNOWN

/* Whether index or not the name of a file whose content type is text/plain
   or text/html. */
#define INDEX_CONTENT_FILE_NAMES

/* Bits of the characters which are permited to be in the indexed words */
#define WORD_CHAR_BITS                 (CHAR_ENGLISH | CHAR_RUSSIAN | CHAR_DIGIT)
/* #define BEGIN_WORD_CHAR_BITS           WORD_CHAR_BITS */
/* #define END_WORD_CHAR_BITS             WORD_CHAR_BITS */

/* The maximum times a letter can repeat in a word. */
/* #define MAX_EQUAL_SEQUENCE_SIZE        3 */

/* The maximum number of consecutive vowels a word can have. */
/* #define MAX_VOWEL_SEQUENCE_SIZE        5 */

/* The maximum number of consecutive consonants a word can have. */
/* #define MAX_CONSONANT_SEQUENCE_SIZE    6 */

/* The maximum number of consecutive digits a word can have. */
/* #define MAX_DIGIT_SEQUENCE_SIZE        20 */

/* Don't index words containing english and russian letters in one. */
#define SINGLE_LANGUAGE_WORDS

/* Don't index words containing only digits (such as '123'). */
/* #define IGNORE_ALL_DIGITS_WORD */

/* Don't index words containing only consonants (such as 'pts'). */
/* #define IGNORE_ALL_CONSONANTS_WORD */

/* Don't index words containing only vowels (such as 'aeu'). */
/* #define IGNORE_ALL_VOWELS_WORD */

/***************************************************************************/
/*                                                                         */
/*  Searching options                                                      */
/*                                                                         */
/***************************************************************************/

/* MAX_HITS is the maximum number of results to return from a search.
   You could define it as -1 for all results. Used in flsearch only. */
#define MAX_HITS                       -1

/* If a list of search words is specified without booleans,
   FLUIdS will assume they are tied by a default operation.
   This should be optAnd or optOr. */
#define DEFAULT_OPERATION              optAnd

#define SUBWORD_SEARCH

/***************************************************************************/
/*                                                                         */
/*  FLUIdS CGI options                                                     */
/*                                                                         */
/***************************************************************************/

#define FLUIDS_CONF_FILE               "fluids.cfg"
#define FLUIDS_ROOT_DIR                "~"

#define FLUIDS_CYR_REPLACE
#define DEFAULT_TERSE_LEVEL            trsDetailed

#define DEFAULT_PAGE_SIZE              20

#define MAX_PAGES_PER_BLOCK            15

#define DEFAULT_QUERY_TYPE             qtpExternalForm

#define DEFAULT_USER_OPTIONS \
    (USEROPTION_FLUIDS_LOGO | USEROPTION_META_CHARSET_TAG |\
     USEROPTION_CHARSET_LIST | USEROPTION_SEARCH_TIME |\
     USEROPTION_EXECUTED_QUERY | USEROPTION_PROBLEM_WORDS |\
     USEROPTION_LOGO_SPECIAL_EFFECTS | USEROPTION_ESCAPED_URLS)

/* #define FULL_FILE_NAMES */

#endif

#ifndef __DEFS_A
#define __DEFS_A

#ifndef __ZDEFS_A
#endif

/* #define FLUIDS43 */

#if SIZEOF_INT < 4
typedef unsigned int _fn_t;
#else
typedef unsigned zint_t _fn_t;
#endif
typedef unsigned zint_t _rn_t;
typedef unsigned zshort_t _st_t;

#if SIZEOF_INT < 4
#define MAX_FILENUM                    (10*1024-1)
#else
#define MAX_FILENUM                    __ZINT(0x1fffffu)
#endif
#define MAX_RANK                       __ZINT(4294967295u)

#if SIZEOF_INT < 4
#define PRINTFORMAT_FILENUM            "%u"
#else
#define PRINTFORMAT_FILENUM            "%" _ZINT_FORMAT "u"
#endif
#define PRINTFORMAT_RANK               "%" _ZINT_FORMAT "u"

#if defined( FLUIDS43 )
#define VERSION                        "4.3a"
#define INDEX_VERSION                  0
#define INDEX_SUBVERSION               40
#else
#define VERSION                        "4.2.4"
#define INDEX_VERSION                  4
#define INDEX_SUBVERSION               3
#endif

#define MAX_STRING_LENGTH              1024
#define MAX_FILENAME_LENGTH            1024

#define MAX_WORD_SIZE                  64
#define ITEM_LIST_SIZE                 1001

#define MAX_TEMPLATE_STRING_SIZE       (4*1024)

#define INDEX_FILE_ENDIAN              True

#define MAX_REF_SIZE                   (4*1024)

#endif

#ifndef __SEARCHER_A
#define __SEARCHER_A

#ifndef __ZDEFS_A
#endif

#ifndef __ZTIME_A
#endif

#ifdef __cplusplus
extern "C" {
#endif

struct expression_t;
struct indexfile_t;
struct flu_searcher_t;
struct flu_searcher_data_t;
struct flu_searcher_result_t;

typedef void (*flu_searcher_printerror_t)( struct flu_searcher_t *, unsigned zint_t, const char *);
typedef void (*flu_searcher_memfail_t)( struct flu_searcher_t *, const char *);
typedef Boolean (*flu_searcher_printresult_t)( struct flu_searcher_t *, struct flu_searcher_result_t *);

struct flu_searcher_indexfile_t
{
/* Index file */
  struct indexfile_t *pif;
  Boolean isOpen;
  Boolean wasOpen;
  Boolean wasError;

/* Other */
  int number;
  void *info;
  int foundCount;
};

struct flu_searcher_t
{
  struct zcontext_t *context;
  unsigned zint_t errorCode;
  int allocCount;

/* User info */
  flu_searcher_printerror_t printError;
  flu_searcher_memfail_t memoryFail;
  unsigned int searchArea;
  unsigned int searchFlags;
  int startNumber;
  int resultCount;
  void *info;
  int step;
  const char *query;

/* Index list */
  struct flu_searcher_indexfile_t *indexes;
  int indexCount;

/* Search data */
  struct expression_t *q;
  struct ztimeval_t *startTime;
  struct ztimeval_t *endTime;
  int foundCount;
  int printCount;
  float maxRank;

/* Main pointer */
  struct flu_searcher_data_t *ptr;
};

struct flu_searcher_result_t
{
/* External data */
  Boolean wasError;
  int number;
  struct flu_searcher_indexfile_t *indexFile;

/* Internal data */
  int rank;
  char *url;
  char *title;
  char *content;
  int urlLength;
  int titleLength;
  int contentLength;
  zoff_t size;
  ztime_t lastModified;
  Boolean allContent;
};

#define FLU_SEARCHER_FLAG_HAVE_RESULT_WINDOW     0x0001u
#define FLU_SEARCHER_FLAG_MEMORY_FAIL            0x0100u

enum
{
  fssStepDone,
  fssStepInit,
  fssStepCompile,
  fssStepSearch,
  fssStepPrinting
};

ZAPI(Boolean) fluSearcherInit( struct flu_searcher_t *fs,
    flu_searcher_printerror_t printError, flu_searcher_memfail_t memoryFail,
    void *info);
ZAPI(void) fluSearcherFree( struct flu_searcher_t *fs );
ZAPI(const char *) fluSearcherErrorString( struct flu_searcher_t *fs,
    unsigned zint_t errorCode, const char *name);

#define FS_AREA_KEYWORD                0x0001u
#define FS_AREA_CONTENT                0x0002u
#define FS_AREA_TITLE                  0x0004u
#define FS_AREA_FILENAME               0x0008u
#define FS_AREA_ANY                    0x000fu

#define fsfCaseDepend                  0x0001u
#define fsfStopOnError                 0x0002u
#define fsfShortForm                   0x0004u
#define fsfFoundCount                  0x0008u
#define fsfExtended                    0x0010u
/* XXX: На будущее! */
#define fsfDateSorted                  0x0100u
#define fsfSizeSorted                  0x0200u
#define fsfUnsorted                    0x0400u
#define fsfDowngradeSorting            0x0800u

ZAPI(Boolean) fluSearcherSetParams( struct flu_searcher_t *fs,
    unsigned int searchArea, unsigned int searchFlags,
    int startNumber, int resultCount);
ZAPI(Boolean) fluSearcherSetQuery( struct flu_searcher_t *fs, const char *query);

ZAPI(Boolean) fluSearcherMakeSearch( struct flu_searcher_t *fs, int count,
    const char **indexes, const char **aliases, void **infos);

ZAPI(Boolean) fluSearcherPrintResults( struct flu_searcher_t *fs,
    flu_searcher_printresult_t printResult, unsigned int flags);
ZAPI(Boolean) fluSearcherInitResult( struct flu_searcher_t *fs, unsigned int flags);
ZAPI(struct flu_searcher_result_t *) fluSearcherNextResult( struct flu_searcher_t *fs );

#ifdef __cplusplus
}
#endif

#endif

#ifndef __FLUINIT_A
#define __FLUINIT_A

#ifndef __ZDEFS_A
#endif

#ifdef __cplusplus
extern "C" {
#endif

ZAPI(void) fluInit( void );

#ifdef __cplusplus
}
#endif

#endif

