/*
    Locale support implementation through OS/2 Unicode API.
    Copyright (c) 2003 InnoTek Systemberatung GmbH

    For conditions of distribution and use, see the file COPYING.

    Private header file for locale support.
*/

#ifndef __SYS_LOCALE_H__
#define __SYS_LOCALE_H__

/* To avoid conflicts with unidef.h we should use same values as there. */
#define LC_ALL			(-1)
#define LC_COLLATE		0
#define LC_CTYPE		1
#define LC_NUMERIC		2
#define LC_MONETARY		3
#define LC_TIME			4
#define LC_MESSAGES		5
#define __LC_COUNT 6

/* Bit masks for __locale_global.ctype -
   !NOTE! - these have identical values to the CT_* to speed up setlocale(). */
#define __UPPER     0x0001      /* Upper case alphabetic character. */
#define __LOWER     0x0002      /* Lower case alphabetic character. */
#define __DIGIT     0x0004      /* Digits 0-9. */
#define __SPACE     0x0008      /* White space and line ends. */
#define __PUNCT     0x0010      /* Punctuation marks. */
#define __CNTRL     0x0020      /* Control and format characters. */
#define __BLANK     0x0040      /* Space and tab. */
#define __XDIGIT    0x0080      /* Hex digits. */
#define __ALPHA     0x0100      /* Letters and linguistic marks. */
#define __ALNUM     0x0200      /* Alphanumeric. */
#define __GRAPH     0x0400      /* All except controls and space. */
#define __PRINT     0x0800      /* Everything except controls. */
#define __NUMBER    0x1000      /* Integral number. */
#define __SYMBOL    0x2000      /* Symbol. */
#define __ASCII     0x8000      /* In standard ASCII set. */

/* Locale information structure. */
struct lconv
{
  char *decimal_point;		/* non-monetary decimal point */
  char *thousands_sep;		/* non-monetary thousands separator */
  char *grouping;		/* non-monetary size of grouping */
  char *int_curr_symbol;	/* international currency symbol and separator */
  char *currency_symbol;	/* local currency symbol */
  char *mon_decimal_point;	/* monetary decimal point */
  char *mon_thousands_sep;	/* monetary thousands separator */
  char *mon_grouping;		/* monetary size of grouping */
  char *positive_sign;		/* non-negative values sign */
  char *negative_sign;		/* negative values sign */
  char int_frac_digits;		/* number of fractional digits - int currency */
  char frac_digits;		/* number of fractional digits - local currency */
  char p_cs_precedes;		/* (non-neg curr sym) 1-precedes, 0-succeeds */
  char p_sep_by_space;		/* (non-neg curr sym) 1-space, 0-no space */
  char n_cs_precedes;		/* (neg curr sym) 1-precedes, 0-succeeds */
  char n_sep_by_space;		/* (neg curr sym) 1-space, 0-no space */
  char p_sign_posn;		/* positioning of non-negative monetary sign */
  char n_sign_posn;		/* positioning of negative monetary sign */
  /** @todo C99
char     int_n_cs_precedes
char     int_n_sep_by_space
char     int_n_sign_posn
char     int_p_cs_precedes
char     int_p_sep_by_space
char     int_p_sign_posn
  */
};


#ifdef __INTERNAL_DEFS

#include <uconv.h>

/* This structure keeps the time formatting rules. */
struct __locale_time
{
  char *smonths [12];		/* Short month names */
  char *lmonths [12];		/* Long month names */
  char *swdays [7];		/* Short weekday names */
  char *lwdays [7];		/* Long weekday names */
  char *date_time_fmt;		/* Date and time format */
  char *date_fmt;		/* Date format */
  char *time_fmt;		/* Time format */
  char *am, *pm;		/* AM and PM strings */
};

/* There is one global object of this type that contains integral
   information about last selected (with setlocale()) locale.
   The locale information itself is split into parts to avoid linking
   unused data into programs that use just the "C" locale and just
   a few functions that use locale data (such as strdate()). */
struct __locale_global
{
  /* Lock for multi-threaded operations. */
  signed char /* _smutex */ lock; /* Avoid including builtin.h & smutex.h */
  /* Category names. */
  char *name [__LC_COUNT + 1];
};

/* This structure contains the uppercase/lowercase tables. */
struct __locale_ctype
{
  /* Bit flags for every character (for isXXX() function series) */
  unsigned short cflags [256];
  /* All uppercased characters */
  unsigned char upcase [256];
  /* All lowercased characters */
  unsigned char locase [256];
  /* MBCS prefixes. Two bits per character. */
  unsigned char mbcsprefix [256/4];
  /* The converter object to convert to and from selected codepage
     (used with MBCS codepages only) */
  UconvObject uconv;
  /* The locale object. */
  LocaleObject locale;
  /* Non-zero if there are any MBCS prefix characters in codepage */
  char mbcs;
};

struct __locale_collate
{
  /* Character weight for SBCS codepages */
  unsigned char weight [256];
  /* MBCS prefixes. Two bits per character. */
  unsigned char mbcsprefix [256/4];
  /* The converter object to convert to and from selected codepage
     (used with MBCS codepages only) */
  UconvObject uconv;
  /* The locale object. */
  LocaleObject locale;
  /* Non-zero if there are any MBCS prefix characters in codepage */
  char mbcs;
};

/* Handy macros for working with (__locale_ctype|__locale_collate).mbcsprefix */
#define SET_MBCS_PREFIX(s,c,v) \
  s [((unsigned char)c) >> 2] |= (v) << (2 * ((c) & 3))
#define LEN_MBCS_PREFIX(s,c) \
  ((s [((unsigned char)c) >> 2] >> (2 * ((c & 3) ^ 3))) & 3)
#define IS_MBCS_PREFIX(s,c) \
  (LEN_MBCS_PREFIX(s.mbcsprefix,c) != 1)
#define CHK_MBCS_PREFIX(s,c,v) \
  ((v = LEN_MBCS_PREFIX(s.mbcsprefix,c)) > 1)

/* A static constant string denoting the "C" locale. */
extern const char __locale_C[2];

/* Global locale information. */
extern struct __locale_global __locale;
/* String collation information. */
extern struct __locale_collate __locale_collate;
/* Character case conversion tables. */
extern struct __locale_ctype __locale_ctype;
/* Locale information structure. */
extern struct lconv __locale_lconv;
/* Date / time formatting rules. */
extern struct __locale_time __locale_time;

/* Convert a string to Unicode, apply some transform and convert back. */
extern void __do_Unicode (UconvObject *uconv, char *s, void *arg,
  int (*xform) (UniChar *, void *));
/* Convert a MBCS character to Unicode; returns number of bytes in MBCS char. */
extern int __to_ucs (UconvObject, const unsigned char *, size_t, UniChar *);
/* Convert a Unicode character to MBCS */
extern int __from_ucs (UconvObject, UniChar, unsigned char *, size_t);

#else

/* Simplified extern definitions for inline functions usage */

/* Character case conversion tables. */
extern struct
{
  unsigned short cflags [256];
  unsigned char upcase [256];
  unsigned char locase [256];
} __locale_ctype;

#endif /* __INTERNAL_DEFS */

#endif /* __SYS_LOCALE_H__ */
