* Copied imported OpenTracker Locale Kit files from the vendor branch

into their new homes (at least for now, might need some adjustment).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30540 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Tappe 2009-05-01 19:23:59 +00:00
parent 4465d9277f
commit c3ac87e8fc
107 changed files with 26864 additions and 0 deletions

350
headers/os/locale/Catalog.h Normal file
View File

@ -0,0 +1,350 @@
#ifndef _CATALOG_H_
#define _CATALOG_H_
#include <LocaleBuild.h>
#include <SupportDefs.h>
#include <String.h>
class BCatalogAddOn;
class BLocale;
class BMessage;
struct entry_ref;
class _IMPEXP_LOCALE BCatalog {
public:
BCatalog();
BCatalog(const char *signature, const char *language = NULL,
int32 fingerprint = 0);
virtual ~BCatalog();
const char *GetString(const char *string, const char *context = NULL,
const char *comment = NULL);
const char *GetString(uint32 id);
status_t GetData(const char *name, BMessage *msg);
status_t GetData(uint32 id, BMessage *msg);
status_t GetSignature(BString *sig);
status_t GetLanguage(BString *lang);
status_t GetFingerprint(int32 *fp);
status_t InitCheck() const;
int32 CountItems() const;
BCatalogAddOn *CatalogAddOn();
protected:
BCatalog(const BCatalog&);
const BCatalog& operator= (const BCatalog&);
// hide assignment and copy-constructor
static status_t GetAppCatalog(BCatalog*);
BCatalogAddOn *fCatalog;
private:
friend class BLocale;
friend status_t get_add_on_catalog(BCatalog*, const char *);
};
extern _IMPEXP_LOCALE BCatalog* be_catalog;
extern _IMPEXP_LOCALE BCatalog* be_app_catalog;
#ifndef B_AVOID_TRANSLATION_MACROS
// macros for easy catalog-access, define B_AVOID_TRANSLATION_MACROS if
// you don't want these:
#undef TR_CONTEXT
// In a single application, several strings (e.g. 'Ok') will be used
// more than once, in different contexts.
// As the application programmer can not know if all translations of
// this string will be the same for all languages, each occurrence of
// the string must be translated on its own.
// Specifying the context explicitly with each string allows the person
// translating a catalog to separate these different occurrences of the
// same string and tell which strings appears in what context of the
// application.
// In order to give the translator a useful hint, the application
// programmer needs to define TR_CONTEXT with the context he'd like
// to be associated with the strings used in this specifc source file.
// example:
// #define TR_CONTEXT "Folder-Window"
// Tip: Use a descriptive name of the class implemented in that
// source-file.
// Translation macros which may be used to shorten translation requests:
#undef TR
#define TR(str) \
be_catalog->GetString((str), TR_CONTEXT)
#undef TR_CMT
#define TR_CMT(str,cmt) \
be_catalog->GetString((str), TR_CONTEXT, (cmt))
#undef TR_ALL
#define TR_ALL(str,ctx,cmt) \
be_catalog->GetString((str), (ctx), (cmt))
#undef TR_ID
#define TR_ID(id) \
be_catalog->GetString((id))
// Translation markers which can be used to mark static strings/IDs which
// are used as key for translation requests (at other places in the code):
/* example:
#define TR_CONTEXT "MyDecentApp-Menu"
static const char *choices[] = {
TR_MARK("left"),
TR_MARK("right"),
TR_MARK("up"),
TR_MARK("down")
};
void MyClass::AddChoices(BMenu *menu) {
for (char **ch = choices; *ch; ch++) {
menu->AddItem(
new BMenuItem(
TR(*ch),
new BMessage(...)
)
)
}
}
*/
#undef TR_MARK
#define TR_MARK(str) \
BCatalogAddOn::MarkForTranslation((str), TR_CONTEXT, "")
#undef TR_MARK_CMT
#define TR_MARK_CMT(str,cmt) \
BCatalogAddOn::MarkForTranslation((str), TR_CONTEXT, (cmt))
#undef TR_MARK_ALL
#define TR_MARK_ALL(str,ctx,cmt) \
BCatalogAddOn::MarkForTranslation((str), (ctx), (cmt))
#undef TR_MARK_ID
#define TR_MARK_ID(id) \
BCatalogAddOn::MarkForTranslation((id))
#endif /* B_AVOID_TRANSLATION_MACROS */
/************************************************************************/
// For BCatalog add-on implementations:
class _IMPEXP_LOCALE BCatalogAddOn {
friend class BLocaleRoster;
public:
BCatalogAddOn(const char *signature, const char *language,
int32 fingerprint);
virtual ~BCatalogAddOn();
virtual const char *GetString(const char *string,
const char *context=NULL,
const char *comment=NULL) = 0;
virtual const char *GetString(uint32 id) = 0;
status_t InitCheck() const;
BCatalogAddOn *Next();
// the following could be used to localize non-textual data (e.g. icons),
// but these will only be implemented if there's demand for such a
// feature:
virtual bool CanHaveData() const;
virtual status_t GetData(const char *name, BMessage *msg);
virtual status_t GetData(uint32 id, BMessage *msg);
// interface for catalog-editor-app and testing apps:
virtual status_t SetString(const char *string,
const char *translated,
const char *context=NULL,
const char *comment=NULL);
virtual status_t SetString(int32 id, const char *translated);
//
virtual bool CanWriteData() const;
virtual status_t SetData(const char *name, BMessage *msg);
virtual status_t SetData(uint32 id, BMessage *msg);
//
virtual status_t ReadFromFile(const char *path = NULL);
virtual status_t ReadFromAttribute(entry_ref *appOrAddOnRef);
virtual status_t ReadFromResource(entry_ref *appOrAddOnRef);
virtual status_t WriteToFile(const char *path = NULL);
virtual status_t WriteToAttribute(entry_ref *appOrAddOnRef);
virtual status_t WriteToResource(entry_ref *appOrAddOnRef);
//
virtual void MakeEmpty();
virtual int32 CountItems() const;
// magic marker functions which are used to mark a string/id
// which will be translated elsewhere in the code (where it can
// not be found since it is references by a variable):
static const char *MarkForTranslation(const char *str, const char *ctx,
const char *cmt);
static int32 MarkForTranslation(int32 id);
protected:
virtual void UpdateFingerprint();
status_t fInitCheck;
BString fSignature;
BString fLanguageName;
int32 fFingerprint;
BCatalogAddOn *fNext;
friend class BCatalog;
friend status_t get_add_on_catalog(BCatalog*, const char *);
};
// every catalog-add-on should export these symbols...
// ...the function that instantiates a catalog for this add-on-type...
extern "C" _IMPEXP_LOCALE
BCatalogAddOn *instantiate_catalog(const char *signature,
const char *language, int32 fingerprint);
// ...the function that creates an empty catalog for this add-on-type...
extern "C" _IMPEXP_LOCALE
BCatalogAddOn *create_catalog(const char *signature,
const char *language);
// ...and the priority which will be used to order the catalog-add-ons:
extern _IMPEXP_LOCALE uint8 gCatalogAddOnPriority;
/*
* BCatalog - inlines for trivial accessors:
*/
inline status_t
BCatalog::GetSignature(BString *sig)
{
if (!sig)
return B_BAD_VALUE;
if (!fCatalog)
return B_NO_INIT;
*sig = fCatalog->fSignature;
return B_OK;
}
inline status_t
BCatalog::GetLanguage(BString *lang)
{
if (!lang)
return B_BAD_VALUE;
if (!fCatalog)
return B_NO_INIT;
*lang = fCatalog->fLanguageName;
return B_OK;
}
inline status_t
BCatalog::GetFingerprint(int32 *fp)
{
if (!fp)
return B_BAD_VALUE;
if (!fCatalog)
return B_NO_INIT;
*fp = fCatalog->fFingerprint;
return B_OK;
}
inline status_t
BCatalog::InitCheck() const
{
return fCatalog
? fCatalog->InitCheck()
: B_NO_INIT;
}
inline int32
BCatalog::CountItems() const
{
if (!fCatalog)
return 0;
return fCatalog->CountItems();
}
inline BCatalogAddOn *
BCatalog::CatalogAddOn()
{
return fCatalog;
}
/*
* BCatalogAddOn - inlines for trivial accessors:
*/
inline BCatalogAddOn *
BCatalogAddOn::Next()
{
return fNext;
}
inline const char *
BCatalogAddOn::MarkForTranslation(const char *str, const char *ctx,
const char *cmt)
{
return str;
}
inline int32
BCatalogAddOn::MarkForTranslation(int32 id)
{
return id;
}
namespace BPrivate {
/*
* EditableCatalog
*/
class _IMPEXP_LOCALE EditableCatalog : public BCatalog {
public:
EditableCatalog(const char *type, const char *signature,
const char *language);
~EditableCatalog();
status_t SetString(const char *string,
const char *translated,
const char *context=NULL,
const char *comment=NULL);
status_t SetString(int32 id, const char *translated);
//
bool CanWriteData() const;
status_t SetData(const char *name, BMessage *msg);
status_t SetData(uint32 id, BMessage *msg);
//
status_t ReadFromFile(const char *path = NULL);
status_t ReadFromAttribute(entry_ref *appOrAddOnRef);
status_t ReadFromResource(entry_ref *appOrAddOnRef);
status_t WriteToFile(const char *path = NULL);
status_t WriteToAttribute(entry_ref *appOrAddOnRef);
status_t WriteToResource(entry_ref *appOrAddOnRef);
//
void MakeEmpty();
private:
EditableCatalog();
EditableCatalog(const EditableCatalog&);
const EditableCatalog& operator= (const EditableCatalog&);
// hide assignment, default- and copy-constructor
};
} // namespace BPrivate
#endif /* _CATALOG_H_ */

View File

@ -0,0 +1,120 @@
#ifndef _CATALOG_IN_ADD_ON_H_
#define _CATALOG_IN_ADD_ON_H_
#include <Catalog.h>
#include <Entry.h>
#include <Locale.h>
#include <LocaleRoster.h>
#include <Node.h>
#include <TypeConstants.h>
/*
* This header file is somewhat special...
*
* Since the TR-macros are referencing be_catalog, we want each add-on
* to have its own be_catalog (instead of sharing the one from the lib).
* In order to do so, we define another be_catalog in this file, which
* will override the one from liblocale.so.
* This way we implement something like add-on-local storage. It would
* be desirable to find a better way, so please tell us if you know one!
*
* Every add-on that wants to use the Locale Kit needs to include this
* file once (no more, exactly once!).
* You have to include it in the source-file that loads the add-on's
* catalog (by use of get_add_on_catalog().
*
*/
BCatalog *be_catalog = NULL;
// global that points to this add-on's catalog
/*
* utility function which determines the entry-ref for "this" add-on:
*/
static status_t
get_add_on_ref(entry_ref *ref)
{
if (!ref)
return B_BAD_VALUE;
image_info imageInfo;
int32 cookie = 0;
status_t res = B_ERROR;
void *dataPtr = static_cast<void*>(&be_catalog);
while ((res = get_next_image_info(0, &cookie, &imageInfo)) == B_OK) {
char *dataStart = static_cast<char*>(imageInfo.data);
if (imageInfo.type == B_ADD_ON_IMAGE && dataStart <= dataPtr
&& dataStart+imageInfo.data_size > dataPtr) {
get_ref_for_path(imageInfo.name, ref);
break;
}
}
return res;
}
/*
* Every add-on should load its catalog through this function, since
* it does not only load the add-on's catalog, but it does several
* other useful things:
* - be_catalog (the one belonging to this add-on) is initialized
* such that the TR-macros use the add-on's catalog.
* - if givenSig is empty (NULL or "") the add-on's signature is
* used to determine the catalog-sig.
* - if the add-on's executable contains an embedded catalog, that
* one is loaded, too.
*/
status_t
get_add_on_catalog(BCatalog* cat, const char *givenSig)
{
if (!cat)
return B_BAD_VALUE;
// determine entry-ref of the add-on this code lives in:
entry_ref ref;
status_t res = get_add_on_ref(&ref);
if (res == B_OK) {
// ok, we have found the entry-ref for our add-on,
// so we try to fetch the fingerprint from our add-on-file:
int32 fp = 0;
BNode addOnNode(&ref);
addOnNode.ReadAttr(BLocaleRoster::kCatFingerprintAttr,
B_INT32_TYPE, 0, &fp, sizeof(int32));
BString sig(givenSig);
if (sig.Length() == 0) {
res = addOnNode.ReadAttrString("BEOS:MIME", &sig);
if (res == B_OK) {
// drop supertype from mimetype (should be "application/"):
int32 pos = sig.FindFirst('/');
if (pos >= 0)
sig.Remove(0, pos+1);
}
}
if (res == B_OK) {
// try to load it's catalog...
cat->fCatalog
= be_locale_roster->LoadCatalog(sig.String(), NULL, fp);
// ...and try to load an embedded catalog, too (if that exists):
BCatalogAddOn *embeddedCatalog
= be_locale_roster->LoadEmbeddedCatalog(&ref);
if (embeddedCatalog) {
if (!cat->fCatalog)
// embedded catalog is the only catalog that was found:
cat->fCatalog = embeddedCatalog;
else {
// append embedded catalog to list of loaded catalogs:
BCatalogAddOn *currCat = cat->fCatalog;
while (currCat->fNext)
currCat = currCat->fNext;
currCat->fNext = embeddedCatalog;
}
}
be_catalog = cat;
}
}
return cat->InitCheck();
}
#endif /* _CATALOG_IN_ADD_ON_H_ */

View File

@ -0,0 +1,119 @@
#ifndef _COLLATOR_H_
#define _COLLATOR_H_
#include <SupportDefs.h>
#include <Archivable.h>
#include <LocaleBuild.h>
class BString;
class BCollatorAddOn;
enum collator_strengths {
B_COLLATE_DEFAULT = -1,
B_COLLATE_PRIMARY = 1, // e.g.: no diacritical differences, e = é
B_COLLATE_SECONDARY, // diacritics are different from their base characters, a != ä
B_COLLATE_TERTIARY, // case sensitive comparison
B_COLLATE_QUATERNARY,
B_COLLATE_IDENTICAL = 127 // Unicode value
};
class _IMPEXP_LOCALE BCollator : public BArchivable {
public:
BCollator();
BCollator(BCollatorAddOn *collator, int8 strength, bool ignorePunctuation);
BCollator(BMessage *archive);
~BCollator();
void SetDefaultStrength(int8 strength);
int8 DefaultStrength() const;
void SetIgnorePunctuation(bool ignore);
bool IgnorePunctuation() const;
status_t GetSortKey(const char *string, BString *key, int8 strength = B_COLLATE_DEFAULT);
int Compare(const char *, const char *, int32 len = -1, int8 strength = B_COLLATE_DEFAULT);
bool Equal(const char *, const char *, int32 len = -1, int8 strength = B_COLLATE_DEFAULT);
bool Greater(const char *, const char *, int32 len = -1, int8 strength = B_COLLATE_DEFAULT);
bool GreaterOrEqual(const char *, const char *, int32 len = -1, int8 strength = B_COLLATE_DEFAULT);
// (un-)archiving API
status_t Archive(BMessage *archive, bool deep) const;
static BArchivable *Instantiate(BMessage *archive);
private:
BCollatorAddOn *fCollator;
image_id fCollatorImage;
int8 fStrength;
bool fIgnorePunctuation;
};
inline bool
BCollator::Equal(const char *s1, const char *s2, int32 len, int8 strength)
{
return Compare(s1, s2, len, strength) == 0;
}
inline bool
BCollator::Greater(const char *s1, const char *s2, int32 len, int8 strength)
{
return Compare(s1, s2, len, strength) > 0;
}
inline bool
BCollator::GreaterOrEqual(const char *s1, const char *s2, int32 len, int8 strength)
{
return Compare(s1, s2, len, strength) >= 0;
}
/************************************************************************/
// For BCollator add-on implementations:
class _IMPEXP_LOCALE BCollatorAddOn : public BArchivable {
public:
BCollatorAddOn();
BCollatorAddOn(BMessage *archive);
virtual ~BCollatorAddOn();
virtual status_t GetSortKey(const char *string, BString *key, int8 strength,
bool ignorePunctuation);
virtual int Compare(const char *a, const char *b, int32 length, int8 strength,
bool ignorePunctuation);
// (un-)archiving API
virtual status_t Archive(BMessage *archive, bool deep) const;
static BArchivable *Instantiate(BMessage *archive);
protected:
struct input_context {
input_context(bool ignorePunctuation);
bool ignore_punctuation;
uint32 next_char;
int32 reserved1;
int32 reserved2;
};
virtual uint32 GetNextChar(const char **string, input_context &context);
virtual size_t PrimaryKeyLength(size_t length);
virtual char *PutPrimaryKey(const char *string, char *buffer, int32 length,
bool ignorePunctuation);
};
// If your add-on should work with the standard tool to create a language, it
// should export that function. However, once the language file has been written
// only the archived collator is used, and that function won't be called anymore.
extern "C" _IMPEXP_LOCALE BCollatorAddOn *instantiate_collator(void);
#endif /* _COLLATOR_H_ */

View File

@ -0,0 +1,75 @@
#ifndef _COUNTRY_H_
#define _COUNTRY_H_
#include <SupportDefs.h>
#include <LocaleBuild.h>
#include <LocaleStrings.h>
#include <String.h>
enum {
B_METRIC = 0,
B_US
};
class _IMPEXP_LOCALE BCountry {
public:
BCountry();
virtual ~BCountry();
virtual const char *Name() const;
// see definitions below
const char *GetString(uint32 id) const;
// date & time
virtual void FormatDate(char *string,size_t maxSize,time_t time,bool longFormat);
virtual void FormatDate(BString *string,time_t time,bool longFormat);
virtual void FormatTime(char *string,size_t maxSize,time_t time,bool longFormat);
virtual void FormatTime(BString *string,time_t time,bool longFormat);
const char *DateFormat(bool longFormat) const;
const char *TimeFormat(bool longFormat) const;
const char *DateSeparator() const;
const char *TimeSeparator() const;
// numbers
virtual void FormatNumber(char *string,size_t maxSize,double value);
virtual void FormatNumber(BString *string,double value);
virtual void FormatNumber(char *string,size_t maxSize,int32 value);
virtual void FormatNumber(BString *string,int32 value);
const char *DecimalPoint() const;
const char *ThousandsSeparator() const;
const char *Grouping() const;
const char *PositiveSign() const;
const char *NegativeSign() const;
// measurements
virtual int8 Measurement() const;
// monetary
virtual ssize_t FormatMonetary(char *string,size_t maxSize,char *format, ...);
virtual ssize_t FormatMonetary(BString *string,char *format, ...);
const char *CurrencySymbol() const;
const char *InternationalCurrencySymbol() const;
const char *MonDecimalPoint() const;
const char *MonThousandsSeparator() const;
const char *MonGrouping() const;
virtual int32 MonFracDigits() const;
protected:
BCountry(const char **strings);
private:
const char **fStrings;
};
#endif /* _COUNTRY_H_ */

View File

@ -0,0 +1,47 @@
#ifndef _B_CURRENCY_H_
#define _B_CURRENCY_H_
#include <Archivable.h>
#include <Message.h>
#include <String.h>
#include <LocaleBuild.h>
class BLocale;
class _IMPEXP_LOCALE BCurrency : public BArchivable {
public:
BCurrency(const BCurrency &other);
BCurrency(BMessage *archive);
BCurrency(const char *currencyCode);
~BCurrency();
status_t InitCheck() const;
virtual status_t Archive(BMessage *archive, bool deep = true) const;
static BArchivable *Instantiate(BMessage *archive);
const char *CurrencyCode() const;
const char *DefaultSymbol() const;
int32 DefaultFractionDigits() const;
status_t GetSymbol(char *symbol, size_t maxSize,
BLocale *locale = NULL);
status_t GetSymbol(BString *symbol, BLocale *locale = NULL);
BCurrency &operator=(const BCurrency &other);
bool operator==(const BCurrency &other) const;
bool operator!=(const BCurrency &other) const;
private:
BCurrency();
bool _CheckData() const;
void _Unset(status_t error);
BString fCurrencyCode;
BString fDefaultSymbol;
int32 fDefaultFractionDigits;
};
#endif // _B_CURRENCY_H_

View File

@ -0,0 +1,197 @@
#ifndef _DEFAULT_CATALOG_H_
#define _DEFAULT_CATALOG_H_
#ifdef __MWERKS__
# include <hashmap.h>
#else
# include <hash_map>
#endif
#include <LocaleBuild.h>
#include <Catalog.h>
#include <DataIO.h>
#include <String.h>
class BFile;
namespace BPrivate {
struct CatKey;
}
/*
* the hash-access functor which is being used to access the hash-value
* stored inside of each key.
*/
#ifdef __MWERKS__
// Codewarrior doesn't provide this declaration, so we do:
template <class T> struct hash : public unary_function<T,size_t> {
size_t operator() (const T &key) const;
};
#endif
struct hash<BPrivate::CatKey> {
size_t operator() (const BPrivate::CatKey &key) const;
};
namespace BPrivate {
/*
* The key-type for the hash_map which maps native strings or IDs to
* the corresponding translated string.
* The key-type should be efficient to use if it is just created by an ID
* but it should also support being created from up to three strings,
* which as a whole specify the key to the translated string.
*/
struct _IMPEXP_LOCALE CatKey {
BString fKey;
// the key-string consists of three values separated by a special
// token:
// - the native string
// - the context of the string's usage
// - a comment that can be used to separate strings that
// are identical otherwise (useful for the translator)
size_t fHashVal;
// the hash-value of fKey
uint32 fFlags;
// with respect to the catalog-editor, each translation can be
// in different states (empty, unchecked, checked, etc.).
// This state (and potential other flags) lives in the fFlags member.
CatKey(const char *str, const char *ctx, const char *cmt);
CatKey(uint32 id);
CatKey();
bool operator== (const CatKey& right) const;
status_t GetStringParts(BString* str, BString* ctx, BString* cmt) const;
static size_t HashFun(const char* s);
};
/*
* The implementation of the Locale Kit's standard catalog-type.
* Currently it only maps CatKey to a BString (the translated string),
* but the value-type might change to add support for shortcuts and/or
* graphical data (button-images and the like).
*/
class _IMPEXP_LOCALE DefaultCatalog : public BCatalogAddOn {
public:
DefaultCatalog(const char *signature, const char *language,
int32 fingerprint);
// constructor for normal use
DefaultCatalog(entry_ref *appOrAddOnRef);
// constructor for embedded catalog
DefaultCatalog(const char *path, const char *signature,
const char *language);
// constructor for editor-app
~DefaultCatalog();
// overrides of BCatalogAddOn:
const char *GetString(const char *string, const char *context = NULL,
const char *comment = NULL);
const char *GetString(uint32 id);
const char *GetString(const CatKey& key);
//
status_t SetString(const char *string, const char *translated,
const char *context = NULL, const char *comment = NULL);
status_t SetString(int32 id, const char *translated);
status_t SetString(const CatKey& key, const char *translated);
void UpdateFingerprint();
// implementation for editor-interface:
status_t ReadFromFile(const char *path = NULL);
status_t ReadFromAttribute(entry_ref *appOrAddOnRef);
status_t ReadFromResource(entry_ref *appOrAddOnRef);
status_t WriteToFile(const char *path = NULL);
status_t WriteToAttribute(entry_ref *appOrAddOnRef);
status_t WriteToResource(entry_ref *appOrAddOnRef);
//
void MakeEmpty();
int32 CountItems() const;
static BCatalogAddOn *Instantiate(const char *signature,
const char *language,
int32 fingerprint);
static BCatalogAddOn *InstantiateEmbedded(entry_ref *appOrAddOnRef);
static BCatalogAddOn *Create(const char *signature,
const char *language);
static const uint8 kDefaultCatalogAddOnPriority;
static const char *kCatMimeType;
private:
status_t Flatten(BDataIO *dataIO);
status_t Unflatten(BDataIO *dataIO);
int32 ComputeFingerprint() const;
void UpdateAttributes(BFile& catalogFile);
typedef hash_map<CatKey, BString, hash<CatKey>, equal_to<CatKey> > CatMap;
CatMap fCatMap;
mutable BString fPath;
public:
/*
* CatWalker
*/
class CatWalker {
public:
CatWalker() {}
CatWalker(CatMap &catMap);
bool AtEnd() const;
const CatKey& GetKey() const;
const char *GetValue() const;
void Next();
private:
CatMap::iterator fPos;
CatMap::iterator fEnd;
};
status_t GetWalker(CatWalker *walker);
};
inline
DefaultCatalog::CatWalker::CatWalker(CatMap &catMap)
: fPos(catMap.begin()),
fEnd(catMap.end())
{
}
inline bool
DefaultCatalog::CatWalker::AtEnd() const
{
return fPos == fEnd;
}
inline const CatKey &
DefaultCatalog::CatWalker::GetKey() const
{
assert(fPos != fEnd);
return fPos->first;
}
inline const char *
DefaultCatalog::CatWalker::GetValue() const
{
assert(fPos != fEnd);
return fPos->second.String();
}
inline void
DefaultCatalog::CatWalker::Next()
{
++fPos;
}
inline status_t
DefaultCatalog::GetWalker(CatWalker *walker)
{
if (!walker)
return B_BAD_VALUE;
*walker = CatWalker(fCatMap);
return B_OK;
}
} // namespace BPrivate
using namespace BPrivate;
#endif /* _DEFAULT_CATALOG_H_ */

View File

@ -0,0 +1,56 @@
#ifndef _B_FLOAT_FORMAT_H_
#define _B_FLOAT_FORMAT_H_
#include <NumberFormat.h>
#include <FloatFormatParameters.h>
class BString;
class BFloatFormatImpl;
class _IMPEXP_LOCALE BFloatFormat : public BNumberFormat, public BFloatFormatParameters {
public:
BFloatFormat(const BFloatFormat &other);
~BFloatFormat();
// formatting
// no-frills version: Simply appends the formatted number to the
// string buffer. Can fail only with B_NO_MEMORY or B_BAD_VALUE.
status_t Format(double number, BString *buffer) const;
// Appends the formatted number to the string buffer. Additionally
// one can get the positions of certain fields in the formatted
// number by supplying format_field_position structures with the
// field_type set respectively. Passing true for allFieldPositions
// will make the method fill in a format_field_position structure for
// each field it writes -- the field_type values will be ignored and
// overwritten.
// In fieldCount, in case it is non-null, the number of fields
// written is returned.
// B_BUFFER_OVERFLOW is returned, if allFieldPositions is true and
// the positions buffer is too small (fieldCount will be set
// nevertheless, so that the caller can adjust the buffer size to
// make them all fit).
status_t Format(double number, BString *buffer,
format_field_position *positions,
int32 positionCount = 1,
int32 *fieldCount = NULL,
bool allFieldPositions = false) const;
// TODO: Format() versions for (char* buffer, size_t bufferSize)
// instead of BString*. And, of course, versions for the other
// number types (float).
// parsing
// TODO: ...
BFloatFormat &operator=(const BFloatFormat &other);
BFloatFormat(BFloatFormatImpl *impl); // conceptually private
private:
inline BFloatFormatImpl *FloatFormatImpl() const;
};
#endif // _B_FLOAT_FORMAT_H_

View File

@ -0,0 +1,39 @@
#ifndef _B_FLOAT_FORMAT_IMPL_H_
#define _B_FLOAT_FORMAT_IMPL_H_
#include <NumberFormatImpl.h>
struct format_field_position;
class BFloatFormatParameters;
class BString;
class _IMPEXP_LOCALE BFloatFormatImpl : public BNumberFormatImpl {
public:
BFloatFormatImpl();
virtual ~BFloatFormatImpl();
// formatting
virtual status_t Format(const BFloatFormatParameters *parameters,
double number, BString *buffer) const = 0;
virtual status_t Format(const BFloatFormatParameters *parameters,
double number, BString *buffer,
format_field_position *positions,
int32 positionCount = 1,
int32 *fieldCount = NULL,
bool allFieldPositions = false) const = 0;
// TODO: ...
virtual BNumberFormatParameters *DefaultNumberFormatParameters();
virtual const BNumberFormatParameters *DefaultNumberFormatParameters()
const;
virtual BFloatFormatParameters *DefaultFloatFormatParameters() = 0;
virtual const BFloatFormatParameters *DefaultFloatFormatParameters()
const = 0;
};
#endif // _B_FLOAT_FORMAT_IMPL_H_

View File

@ -0,0 +1,54 @@
#ifndef _B_FLOAT_FORMAT_PARAMETERS_H_
#define _B_FLOAT_FORMAT_PARAMETERS_H_
#include <NumberFormatParameters.h>
enum float_format_type {
B_FIXED_POINT_FLOAT_FORMAT,
B_SCIENTIFIC_FLOAT_FORMAT,
B_AUTO_FLOAT_FORMAT, // picks one of the above depending of the
// number to be formatted
};
class _IMPEXP_LOCALE BFloatFormatParameters : public BNumberFormatParameters {
public:
BFloatFormatParameters(const BFloatFormatParameters *parent = NULL);
BFloatFormatParameters(const BFloatFormatParameters &other);
~BFloatFormatParameters();
void SetMinimalFractionDigits(size_t minFractionDigits);
size_t MinimalFractionDigits() const;
void SetMaximalFractionDigits(size_t maxFractionDigits);
size_t MaximalFractionDigits() const;
void SetUseUpperCase(bool useCapitals);
bool UseUpperCase() const;
void SetFloatFormatType(float_format_type type);
float_format_type FloatFormatType() const;
void SetAlwaysUseFractionSeparator(bool alwaysUseFractionSeparator);
bool AlwaysUseFractionSeparator() const;
void SetKeepTrailingFractionZeros(bool keepTrailingFractionZeros);
bool KeepTrailingFractionZeros() const;
void SetParentFloatParameters(const BFloatFormatParameters *parent);
const BFloatFormatParameters *ParentFloatParameters() const;
BFloatFormatParameters &operator=(
const BFloatFormatParameters &other);
private:
const BFloatFormatParameters *fParent;
size_t fMinimalFractionDigits;
size_t fMaximalFractionDigits;
bool fUseUpperCase;
float_format_type fFloatFormatType;
bool fAlwaysUseFractionSeparator;
bool fKeepTrailingFractionZeros;
uint32 fFlags;
};
#endif // _B_FLOAT_FORMAT_PARAMETERS_H_

View File

@ -0,0 +1,48 @@
#ifndef _B_FORMAT_H_
#define _B_FORMAT_H_
#include <FormatParameters.h>
#include <SupportDefs.h>
// types of fields contained in formatted strings
enum {
// number format fields
B_CURRENCY_FIELD,
B_DECIMAL_SEPARATOR_FIELD,
B_EXPONENT_FIELD,
B_EXPONENT_SIGN_FIELD,
B_EXPONENT_SYMBOL_FIELD,
B_FRACTION_FIELD,
B_GROUPING_SEPARATOR_FIELD,
B_INTEGER_FIELD,
B_PERCENT_FIELD,
B_PERMILLE_FIELD,
B_SIGN_FIELD,
// date format fields
// TODO: ...
};
// structure filled in while formatting
struct _IMPEXP_LOCALE format_field_position {
uint32 field_type;
int32 start;
int32 length;
};
class BFormatImpl;
class _IMPEXP_LOCALE BFormat {
protected:
BFormat(const BFormat &other);
~BFormat();
BFormat &operator=(const BFormat &other);
BFormat(BFormatImpl *impl);
protected:
BFormatImpl *fImpl;
};
#endif // _B_FORMAT_H_

View File

@ -0,0 +1,20 @@
#ifndef _B_FORMAT_IMPL_H_
#define _B_FORMAT_IMPL_H_
#include <SupportDefs.h>
#include <LocaleBuild.h>
class BFormatParameters;
class _IMPEXP_LOCALE BFormatImpl {
public:
BFormatImpl();
virtual ~BFormatImpl();
virtual BFormatParameters *DefaultFormatParameters() = 0;
virtual const BFormatParameters *DefaultFormatParameters()
const = 0;
};
#endif // _B_FORMAT_IMPL_H_

View File

@ -0,0 +1,39 @@
#ifndef _B_FORMAT_PARAMETERS_H_
#define _B_FORMAT_PARAMETERS_H_
#include <SupportDefs.h>
#include <LocaleBuild.h>
enum format_alignment {
B_ALIGN_FORMAT_LEFT, // reuse B_ALIGN_LEFT/B_ALIGN_RIGHT?
B_ALIGN_FORMAT_RIGHT,
};
class _IMPEXP_LOCALE BFormatParameters {
public:
BFormatParameters(const BFormatParameters *parent = NULL);
BFormatParameters(const BFormatParameters &other);
~BFormatParameters();
void SetAlignment(format_alignment alignment);
format_alignment Alignment() const;
void SetFormatWidth(size_t width);
size_t FormatWidth() const;
const BFormatParameters *ParentParameters() const;
BFormatParameters &operator=(const BFormatParameters &other);
protected:
void SetParentParameters(const BFormatParameters *parent);
private:
const BFormatParameters *fParent;
format_alignment fAlignment;
size_t fWidth;
uint32 fFlags;
};
#endif // _B_FORMAT_PARAMETERS_H_

View File

@ -0,0 +1,160 @@
#ifndef _B_GENERIC_NUMBER_FORMAT_H_
#define _B_GENERIC_NUMBER_FORMAT_H_
#include <FloatFormatParameters.h>
#include <IntegerFormatParameters.h>
class BString;
struct format_field_position;
class _IMPEXP_LOCALE BGenericNumberFormat {
public:
BGenericNumberFormat();
~BGenericNumberFormat();
status_t FormatInteger(const BIntegerFormatParameters *parameters,
int64 number, BString *buffer,
format_field_position *positions = NULL,
int32 positionCount = 1,
int32 *fieldCount = NULL,
bool allFieldPositions = false) const;
status_t FormatInteger(const BIntegerFormatParameters *parameters,
int64 number, char *buffer, size_t bufferSize,
format_field_position *positions = NULL,
int32 positionCount = 1,
int32 *fieldCount = NULL,
bool allFieldPositions = false) const;
status_t FormatInteger(const BIntegerFormatParameters *parameters,
uint64 number, BString *buffer,
format_field_position *positions = NULL,
int32 positionCount = 1,
int32 *fieldCount = NULL,
bool allFieldPositions = false) const;
status_t FormatInteger(const BIntegerFormatParameters *parameters,
uint64 number, char *buffer, size_t bufferSize,
format_field_position *positions = NULL,
int32 positionCount = 1,
int32 *fieldCount = NULL,
bool allFieldPositions = false) const;
status_t FormatFloat(const BFloatFormatParameters *parameters,
double number, BString *buffer,
format_field_position *positions = NULL,
int32 positionCount = 1,
int32 *fieldCount = NULL,
bool allFieldPositions = false) const;
status_t FormatFloat(const BFloatFormatParameters *parameters,
double number, char *buffer, size_t bufferSize,
format_field_position *positions = NULL,
int32 positionCount = 1,
int32 *fieldCount = NULL,
bool allFieldPositions = false) const;
// default number format parameters
status_t SetDefaultIntegerFormatParameters(
const BIntegerFormatParameters *parameters);
BIntegerFormatParameters *DefaultIntegerFormatParameters();
const BIntegerFormatParameters *DefaultIntegerFormatParameters() const;
status_t SetDefaultFloatFormatParameters(
const BFloatFormatParameters *parameters);
BFloatFormatParameters *DefaultFloatFormatParameters();
const BFloatFormatParameters *DefaultFloatFormatParameters() const;
// other parameters configuring the formatter
status_t SetDigitSymbols(const char **digits);
status_t SetFractionSeparator(const char *decimalSeparator);
status_t SetGroupingInfo(const char **groupingSeparators,
size_t separatorCount, size_t *groupSizes, size_t sizeCount);
status_t SetExponentSymbol(const char *exponentSymbol,
const char *upperCaseExponentSymbol = NULL);
status_t SetSpecialNumberSymbols(const char *nan,
const char *infinity, const char *negativeInfinity = NULL,
const char *upperCaseNaN = NULL,
const char *upperCaseInfinity = NULL,
const char *upperCaseNegativeInfinity = NULL);
status_t SetSignSymbols(const char *plusPrefix,
const char *minusPrefix, const char *padPlusPrefix,
const char *noForcePlusPrefix = NULL, const char *plusSuffix = NULL,
const char *minusSuffix = NULL, const char *padPlusSuffix = NULL,
const char *noForcePlusSuffix = NULL);
status_t SetMantissaSignSymbols(const char *plusPrefix,
const char *minusPrefix, const char *padPlusPrefix,
const char *noForcePlusPrefix = NULL, const char *plusSuffix = NULL,
const char *minusSuffix = NULL, const char *padPlusSuffix = NULL,
const char *noForcePlusSuffix = NULL);
status_t SetExponentSignSymbols(const char *plusPrefix,
const char *minusPrefix, const char *plusSuffix = NULL,
const char *minusSuffix = NULL);
// TODO: Support engineering representation of scientific format (exponent
// is a multiple of 3), i.e. allow setting the number of which the exponent
// must be a multiple of.
private:
class BufferWriter;
class Float;
class GroupingInfo;
class Integer;
class SignSymbols;
struct SpecialNumberSymbols;
struct Symbol {
char *symbol;
int length;
int char_count;
Symbol(const char *symbol = NULL);
~Symbol();
status_t SetTo(const char *symbol);
void Unset() { SetTo(NULL); }
};
status_t FormatInteger(const BIntegerFormatParameters *parameters,
const Integer &integer, char *buffer,
size_t bufferSize,
format_field_position *positions = NULL,
int32 positionCount = 1,
int32 *fieldCount = NULL,
bool allFieldPositions = false) const;
const Symbol *DigitSymbols() const;
const Symbol *FractionSeparator() const;
const GroupingInfo *GetGroupingInfo() const;
const Symbol *ExponentSymbol(bool upperCase = false) const;
const Symbol *NaNSymbol(bool upperCase = false) const;
const Symbol *InfinitySymbol(bool upperCase = false) const;
const Symbol *NegativeInfinitySymbol(bool upperCase = false) const;
void GetSpecialNumberSymbols(bool upperCase,
SpecialNumberSymbols *symbols) const;
const SignSymbols *GetSignSymbols() const;
const SignSymbols *MantissaSignSymbols() const;
const SignSymbols *ExponentSignSymbols() const;
static status_t _SetSymbol(Symbol **symbol, const char *str);
BIntegerFormatParameters fIntegerParameters;
BFloatFormatParameters fFloatParameters;
Symbol *fDigitSymbols;
Symbol *fFractionSeparator;
GroupingInfo *fGroupingInfo;
Symbol *fExponentSymbol;
Symbol *fUpperCaseExponentSymbol;
Symbol *fNaNSymbol;
Symbol *fUpperCaseNaNSymbol;
Symbol *fInfinitySymbol;
Symbol *fUpperCaseInfinitySymbol;
Symbol *fNegativeInfinitySymbol;
Symbol *fUpperCaseNegativeInfinitySymbol;
SignSymbols *fSignSymbols;
SignSymbols *fMantissaSignSymbols;
SignSymbols *fExponentSignSymbols;
};
#endif // _B_GENERIC_NUMBER_FORMAT_H_

View File

@ -0,0 +1,61 @@
#ifndef _B_INTEGER_FORMAT_H_
#define _B_INTEGER_FORMAT_H_
#include <NumberFormat.h>
#include <IntegerFormatParameters.h>
class BIntegerFormatImpl;
class BString;
// Note: BIntegerFormat is derived from BIntegerFormatParameters only due
// to my laziness. The parameters should probably be a private member
// and this class (and its base classes) should mirror the parameters
// classes' accessor methods.
//
class _IMPEXP_LOCALE BIntegerFormat : public BNumberFormat, public BIntegerFormatParameters {
public:
BIntegerFormat(const BIntegerFormat &other);
~BIntegerFormat();
// formatting
// no-frills version: Simply appends the formatted number to the
// string buffer. Can fail only with B_NO_MEMORY or B_BAD_VALUE.
status_t Format(int64 number, BString *buffer) const;
// Appends the formatted number to the string buffer. Additionally
// one can get the positions of certain fields in the formatted
// number by supplying format_field_position structures with the
// field_type set respectively. Passing true for allFieldPositions
// will make the method fill in a format_field_position structure for
// each field it writes -- the field_type values will be ignored and
// overwritten.
// In fieldCount, in case it is non-null, the number of fields
// written is returned.
// B_BUFFER_OVERFLOW is returned, if allFieldPositions is true and
// the positions buffer is too small (fieldCount will be set
// nevertheless, so that the caller can adjust the buffer size to
// make them all fit).
status_t Format(int64 number, BString *buffer,
format_field_position *positions,
int32 positionCount = 1,
int32 *fieldCount = NULL,
bool allFieldPositions = false) const;
// TODO: Format() versions for (char* buffer, size_t bufferSize)
// instead of BString*. And, of course, versions for the other
// number types (uint64, uint32,...).
// parsing
// TODO: ...
BIntegerFormat &operator=(const BIntegerFormat &other);
BIntegerFormat(BIntegerFormatImpl *impl); // conceptually private
private:
inline BIntegerFormatImpl *IntegerFormatImpl() const;
};
#endif // _B_INTEGER_FORMAT_H_

View File

@ -0,0 +1,38 @@
#ifndef _B_INTEGER_FORMAT_IMPL_H_
#define _B_INTEGER_FORMAT_IMPL_H_
#include <NumberFormatImpl.h>
struct format_field_position;
class BIntegerFormatParameters;
class BString;
class _IMPEXP_LOCALE BIntegerFormatImpl : public BNumberFormatImpl {
public:
BIntegerFormatImpl();
virtual ~BIntegerFormatImpl();
// formatting
virtual status_t Format(const BIntegerFormatParameters *parameters,
int64 number, BString *buffer) const = 0;
virtual status_t Format(const BIntegerFormatParameters *parameters,
int64 number, BString *buffer,
format_field_position *positions,
int32 positionCount = 1,
int32 *fieldCount = NULL,
bool allFieldPositions = false) const = 0;
// TODO: ...
virtual BNumberFormatParameters *DefaultNumberFormatParameters();
virtual const BNumberFormatParameters *DefaultNumberFormatParameters()
const;
virtual BIntegerFormatParameters *DefaultIntegerFormatParameters() = 0;
virtual const BIntegerFormatParameters *DefaultIntegerFormatParameters()
const = 0;
};
#endif // _B_INTEGER_FORMAT_IMPL_H_

View File

@ -0,0 +1,22 @@
#ifndef _B_INTEGER_FORMAT_PARAMETERS_H_
#define _B_INTEGER_FORMAT_PARAMETERS_H_
#include <NumberFormatParameters.h>
class _IMPEXP_LOCALE BIntegerFormatParameters : public BNumberFormatParameters {
public:
BIntegerFormatParameters(const BIntegerFormatParameters *parent = NULL);
BIntegerFormatParameters(const BIntegerFormatParameters &other);
~BIntegerFormatParameters();
void SetParentIntegerParameters(const BIntegerFormatParameters *parent);
const BIntegerFormatParameters *ParentIntegerParameters() const;
BIntegerFormatParameters &operator=(
const BIntegerFormatParameters &other);
private:
const BIntegerFormatParameters *fParent;
};
#endif // _B_INTEGER_FORMAT_PARAMETERS_H_

View File

@ -0,0 +1,43 @@
#ifndef _LANGUAGE_H_
#define _LANGUAGE_H_
#include <SupportDefs.h>
#include <LocaleBuild.h>
#include <LocaleStrings.h>
enum script_direction {
B_LEFT_TO_RIGHT = 0,
B_RIGHT_TO_LEFT,
B_TOP_TO_BOTTOM, // seems not to be supported anywhere else?
};
class _IMPEXP_LOCALE BLanguage {
public:
~BLanguage();
// language name, e.g. "english", "deutsch"
const char *Name() const { return fName; }
// ISO-639 language code, e.g. "en", "de"
const char *Code() const { return fCode; }
// ISO-639 language family, e.g. "germanic"
const char *Family() const { return fFamily; }
uint8 Direction() const;
// see definitions below
const char *GetString(uint32 id) const;
private:
friend class BLocaleRoster;
BLanguage(const char *language);
void Default();
char *fName, *fCode, *fFamily, *fStrings[B_NUM_LANGUAGE_STRINGS];
uint8 fDirection;
};
#endif /* _LANGUAGE_H_ */

113
headers/os/locale/Locale.h Normal file
View File

@ -0,0 +1,113 @@
#ifndef _B_LOCALE_H_
#define _B_LOCALE_H_
#include <LocaleBuild.h>
#include <Collator.h>
#include <Language.h>
#include <Country.h>
class BCatalog;
class BString;
class _IMPEXP_LOCALE BLocale {
public:
BLocale();
~BLocale();
BCollator *Collator() const { return fCollator; }
BCountry *Country() const { return fCountry; }
BLanguage *Language() const { return fLanguage; }
// see definitions in LocaleStrings.h
const char *GetString(uint32 id);
void FormatString(char *target, size_t maxSize, char *fmt, ...);
void FormatString(BString *, char *fmt, ...);
void FormatDateTime(char *target, size_t maxSize, const char *fmt, time_t);
void FormatDateTime(BString *, const char *fmt, time_t);
// Country short-hands
void FormatDate(char *target, size_t maxSize, time_t, bool longFormat);
void FormatDate(BString *target, time_t, bool longFormat);
void FormatTime(char *target, size_t maxSize, time_t, bool longFormat);
void FormatTime(BString *target, time_t, bool longFormat);
// Collator short-hands
int StringCompare(const char *, const char *, int32 len = -1, int8 strength = B_COLLATE_DEFAULT) const;
int StringCompare(const BString *, const BString *, int32 len = -1, int8 strength = B_COLLATE_DEFAULT) const;
void GetSortKey(const char *string, BString *key);
status_t GetAppCatalog(BCatalog *);
protected:
BCollator *fCollator;
BLanguage *fLanguage;
BCountry *fCountry;
};
// global objects
extern _IMPEXP_LOCALE BLocale *be_locale;
extern _IMPEXP_LOCALE BLocaleRoster *be_locale_roster;
//----------------------------------------------------------------------
//--- country short-hands inlines ---
inline void
BLocale::FormatDate(char *target, size_t maxSize, time_t timer, bool longFormat)
{
fCountry->FormatDate(target, maxSize, timer, longFormat);
}
inline void
BLocale::FormatDate(BString *target, time_t timer, bool longFormat)
{
fCountry->FormatDate(target, timer, longFormat);
}
inline void
BLocale::FormatTime(char *target, size_t maxSize, time_t timer, bool longFormat)
{
fCountry->FormatTime(target, maxSize, timer, longFormat);
}
inline void
BLocale::FormatTime(BString *target, time_t timer, bool longFormat)
{
fCountry->FormatTime(target, timer, longFormat);
}
//--- locale short-hands inlines ---
// #pragma mark -
inline int
BLocale::StringCompare(const char *string1, const char *string2, int32 length, int8 strength) const
{
return fCollator->Compare(string1, string2, length, strength);
}
inline int
BLocale::StringCompare(const BString *string1, const BString *string2, int32 length, int8 strength) const
{
return fCollator->Compare(string1->String(), string2->String(), length, strength);
}
inline void
BLocale::GetSortKey(const char *string, BString *key)
{
fCollator->GetSortKey(string, key);
}
#endif /* _B_LOCALE_H_ */

View File

@ -0,0 +1,12 @@
#ifndef _B_LOCALE_BUILD_H_
#define _B_LOCALE_BUILD_H_
#if _BUILDING_locale
#define _IMPEXP_LOCALE __declspec(dllexport)
#else
#define _IMPEXP_LOCALE __declspec(dllimport)
#endif
#endif /* _B_LOCALE_BUILD_H_ */

View File

@ -0,0 +1,84 @@
#ifndef _LOCALE_ROSTER_H_
#define _LOCALE_ROSTER_H_
#include <LocaleBuild.h>
#include <String.h>
class BLanguage;
class BLocale;
class BCollator;
class BCountry;
class BCatalog;
class BCatalogAddOn;
namespace BPrivate {
class EditableCatalog;
};
enum {
B_LOCALE_CHANGED = '_LCC',
};
class _IMPEXP_LOCALE BLocaleRoster {
public:
BLocaleRoster();
~BLocaleRoster();
// status_t GetCatalog(BLocale *,const char *mimeType, BCatalog *catalog);
// status_t GetCatalog(const char *mimeType, BCatalog *catalog);
// status_t SetCatalog(BLocale *,const char *mimeType, BCatalog *catalog);
// status_t GetLocaleFor(const char *langCode,const char *countryCode);
status_t GetDefaultCollator(BCollator **) const;
status_t GetDefaultLanguage(BLanguage **) const;
status_t GetDefaultCountry(BCountry **) const;
status_t GetPreferredLanguages(BMessage *) const;
status_t SetPreferredLanguages(BMessage *);
// the message contains one or more 'language'-string-fields
// which contain the language-name(s)
status_t GetInstalledLanguages(BMessage *) const;
// the message contains one or more 'language'-string-fields
// which contain the language-name(s)
status_t GetInstalledCatalogs(BMessage *,
const char* sigPattern = NULL,
const char* langPattern = NULL,
int32 fingerprint = 0) const;
// the message contains...
// status_t GetDefaultLanguage(BLanguage *);
// status_t SetDefaultLanguage(BLanguage *);
static const char *kCatLangAttr;
static const char *kCatSigAttr;
static const char *kCatFingerprintAttr;
//
static const char *kCatManagerMimeType;
static const char *kCatEditorMimeType;
//
static const char *kEmbeddedCatAttr;
static int32 kEmbeddedCatResId;
private:
BCatalogAddOn* LoadCatalog(const char *signature,
const char *language = NULL,
int32 fingerprint = 0);
BCatalogAddOn* LoadEmbeddedCatalog(entry_ref *appOrAddOnRef);
status_t UnloadCatalog(BCatalogAddOn *addOn);
//
BCatalogAddOn* CreateCatalog(const char *type,
const char *signature,
const char *language);
friend class BCatalog;
friend class BPrivate::EditableCatalog;
friend status_t get_add_on_catalog(BCatalog*, const char *);
};
#endif /* _LOCALE_ROSTER_H_ */

View File

@ -0,0 +1,108 @@
#ifndef _LOCALE_STRINGS_H_
#define _LOCALE_STRINGS_H_
enum country_strings {
B_COUNTRY_STRINGS_BASE = 0,
B_DATE_TIME_FORMAT = B_COUNTRY_STRINGS_BASE,
B_DATE_FORMAT,
B_TIME_FORMAT,
B_TIME_AM_PM_FORMAT,
B_SHORT_DATE_TIME_FORMAT,
B_SHORT_DATE_FORMAT,
B_SHORT_TIME_FORMAT,
B_SHORT_TIME_AM_PM_FORMAT,
B_AM_STRING,
B_PM_STRING,
B_DATE_SEPARATOR,
B_TIME_SEPARATOR,
B_GROUPING,
B_DECIMAL_POINT,
B_THOUSANDS_SEPARATOR,
B_POSITIVE_SIGN,
B_NEGATIVE_SIGN,
B_CURRENCY_SYMBOL,
B_INT_CURRENCY_SYMBOL,
B_MON_GROUPING,
B_MON_DECIMAL_POINT,
B_MON_THOUSANDS_SEPARATOR,
B_NUM_COUNTRY_STRINGS,
};
enum language_strings {
B_LANGUAGE_STRINGS_BASE = 100,
B_YESTERDAY_STRING = B_LANGUAGE_STRINGS_BASE,
B_TODAY_STRING,
B_TOMORROW_STRING,
B_FUTURE_STRING,
B_DAY_1, // name of the first day of the week, e.g. Sunday
B_DAY_2, // ...
B_DAY_3, //
B_DAY_4,
B_DAY_5,
B_DAY_6,
B_DAY_7,
B_AB_DAY_1, // abbreviated weekday name, e.g. Sun
B_AB_DAY_2, // ...
B_AB_DAY_3,
B_AB_DAY_4,
B_AB_DAY_5,
B_AB_DAY_6,
B_AB_DAY_7,
B_MON_1, // name of the first month of the year, e.g. January
B_MON_2, // ...
B_MON_3,
B_MON_4,
B_MON_5,
B_MON_6,
B_MON_7,
B_MON_8,
B_MON_9,
B_MON_10,
B_MON_11,
B_MON_12,
B_AB_MON_1, // abbreviated month name, e.g. Jan
B_AB_MON_2, // ...
B_AB_MON_3,
B_AB_MON_4,
B_AB_MON_5,
B_AB_MON_6,
B_AB_MON_7,
B_AB_MON_8,
B_AB_MON_9,
B_AB_MON_10,
B_AB_MON_11,
B_AB_MON_12,
B_YES_EXPRESSION,
B_NO_EXPRESSION,
B_YES_STRING,
B_NO_STRING,
B_NUM_LANGUAGE_STRINGS = B_AB_MON_12 - B_LANGUAGE_STRINGS_BASE,
};
// specials for POSIX compatibility
enum other_locale_strings {
B_OTHER_STRINGS_BASE = 200,
B_CODESET = B_OTHER_STRINGS_BASE,
B_ERA,
B_ERA_DATE_FORMAT,
B_ERA_DATE_TIME_FORMAT,
B_ERA_TIME_FORMAT,
B_ALT_DIGITS
};
#endif /* _LOCALE_STRINGS_H_ */

View File

@ -0,0 +1,23 @@
#ifndef _B_NUMBER_FORMAT_H_
#define _B_NUMBER_FORMAT_H_
#include <Format.h>
#include <NumberFormatParameters.h>
class BNumberFormatImpl;
class _IMPEXP_LOCALE BNumberFormat : public BFormat {
protected:
BNumberFormat(const BNumberFormat &other);
~BNumberFormat();
BNumberFormat &operator=(const BNumberFormat &other);
BNumberFormat(BNumberFormatImpl *impl);
private:
inline BNumberFormatImpl *NumberFormatImpl() const;
};
#endif // _B_NUMBER_FORMAT_H_

View File

@ -0,0 +1,22 @@
#ifndef _B_NUMBER_FORMAT_IMPL_H_
#define _B_NUMBER_FORMAT_IMPL_H_
#include <FormatImpl.h>
struct format_field_position;
class BNumberFormatParameters;
class _IMPEXP_LOCALE BNumberFormatImpl : public BFormatImpl {
public:
BNumberFormatImpl();
virtual ~BNumberFormatImpl();
virtual BFormatParameters *DefaultFormatParameters();
virtual const BFormatParameters *DefaultFormatParameters() const;
virtual BNumberFormatParameters *DefaultNumberFormatParameters() = 0;
virtual const BNumberFormatParameters *DefaultNumberFormatParameters()
const = 0;
};
#endif // _B_NUMBER_FORMAT_IMPL_H_

View File

@ -0,0 +1,66 @@
#ifndef _B_NUMBER_FORMAT_PARAMETERS_H_
#define _B_NUMBER_FORMAT_PARAMETERS_H_
#include <FormatParameters.h>
enum number_format_sign_policy {
B_USE_NEGATIVE_SIGN_ONLY,
B_USE_SPACE_FOR_POSITIVE_SIGN,
B_USE_POSITIVE_SIGN,
};
enum number_format_base {
B_DEFAULT_BASE = -1, // locale default, usually decimal, but
// may be something like roman as well
B_FLEXIBLE_DECIMAL_BASE = 0, // same as B_DECIMAL_BASE when formatting,
// but recognizes octal and hexadecimal
// numbers by prefix when parsing
B_OCTAL_BASE = 8,
B_DECIMAL_BASE = 10,
B_HEXADECIMAL_BASE = 16,
};
class _IMPEXP_LOCALE BNumberFormatParameters : public BFormatParameters {
public:
BNumberFormatParameters(const BNumberFormatParameters *parent = NULL);
BNumberFormatParameters(const BNumberFormatParameters &other);
~BNumberFormatParameters();
void SetUseGrouping(bool useGrouping);
bool UseGrouping() const;
void SetSignPolicy(number_format_sign_policy policy);
number_format_sign_policy SignPolicy() const;
void SetBase(number_format_base base);
number_format_base Base() const;
void SetUseBasePrefix(bool useBasePrefix);
bool UseBasePrefix() const;
void SetMinimalIntegerDigits(size_t minIntegerDigits);
size_t MinimalIntegerDigits() const;
void SetUseZeroPadding(bool zeroPadding);
bool UseZeroPadding() const;
const BNumberFormatParameters *ParentNumberParameters() const;
BNumberFormatParameters &operator=(
const BNumberFormatParameters &other);
protected:
void SetParentNumberParameters(const BNumberFormatParameters *parent);
private:
const BNumberFormatParameters *fParent;
bool fUseGrouping;
number_format_sign_policy fSignPolicy;
number_format_base fBase;
bool fUseBasePrefix;
size_t fMinimalIntegerDigits;
bool fUseZeroPadding;
uint32 fFlags;
};
#endif // _B_NUMBER_FORMAT_PARAMETERS_H_

View File

@ -0,0 +1,235 @@
#ifndef _UNICODE_CHAR_H_
#define _UNICODE_CHAR_H_
#include <SupportDefs.h>
#include <LocaleBuild.h>
enum unicode_char_category
{
// Non-category for unassigned and non-character code points.
B_UNICODE_UNASSIGNED = 0,
B_UNICODE_UPPERCASE_LETTER = 1, // Lu
B_UNICODE_LOWERCASE_LETTER = 2, // Ll
B_UNICODE_TITLECASE_LETTER = 3, // Lt
B_UNICODE_MODIFIER_LETTER = 4, // Lm
B_UNICODE_OTHER_LETTER = 5, // Lo
B_UNICODE_NON_SPACING_MARK = 6, // Mn
B_UNICODE_ENCLOSING_MARK = 7, // Me
B_UNICODE_COMBINING_SPACING_MARK = 8, // Mc
B_UNICODE_DECIMAL_DIGIT_NUMBER = 9, // Nd
B_UNICODE_LETTER_NUMBER = 10, // Nl
B_UNICODE_OTHER_NUMBER = 11, // No
B_UNICODE_SPACE_SEPARATOR = 12, // Zs
B_UNICODE_LINE_SEPARATOR = 13, // Zl
B_UNICODE_PARAGRAPH_SEPARATOR = 14, // Zp
B_UNICODE_CONTROL_CHAR = 15, // Cc
B_UNICODE_FORMAT_CHAR = 16, // Cf
B_UNICODE_PRIVATE_USE_CHAR = 17, // Co
B_UNICODE_SURROGATE = 18, // Cs
B_UNICODE_DASH_PUNCTUATION = 19, // Pd
B_UNICODE_START_PUNCTUATION = 20, // Ps
B_UNICODE_END_PUNCTUATION = 21, // Pe
B_UNICODE_CONNECTOR_PUNCTUATION = 22, // Pc
B_UNICODE_OTHER_PUNCTUATION = 23, // Po
B_UNICODE_MATH_SYMBOL = 24, // Sm
B_UNICODE_CURRENCY_SYMBOL = 25, // Sc
B_UNICODE_MODIFIER_SYMBOL = 26, // Sk
B_UNICODE_OTHER_SYMBOL = 27, // So
B_UNICODE_INITIAL_PUNCTUATION = 28, // Pi
B_UNICODE_FINAL_PUNCTUATION = 29, // Pf
B_UNICODE_GENERAL_OTHER_TYPES = 30, // Cn
B_UNICODE_CATEGORY_COUNT
};
/**
* This specifies the language directional property of a character set.
*/
enum unicode_char_direction {
B_UNICODE_LEFT_TO_RIGHT = 0,
B_UNICODE_RIGHT_TO_LEFT = 1,
B_UNICODE_EUROPEAN_NUMBER = 2,
B_UNICODE_EUROPEAN_NUMBER_SEPARATOR = 3,
B_UNICODE_EUROPEAN_NUMBER_TERMINATOR = 4,
B_UNICODE_ARABIC_NUMBER = 5,
B_UNICODE_COMMON_NUMBER_SEPARATOR = 6,
B_UNICODE_BLOCK_SEPARATOR = 7,
B_UNICODE_SEGMENT_SEPARATOR = 8,
B_UNICODE_WHITE_SPACE_NEUTRAL = 9,
B_UNICODE_OTHER_NEUTRAL = 10,
B_UNICODE_LEFT_TO_RIGHT_EMBEDDING = 11,
B_UNICODE_LEFT_TO_RIGHT_OVERRIDE = 12,
B_UNICODE_RIGHT_TO_LEFT_ARABIC = 13,
B_UNICODE_RIGHT_TO_LEFT_EMBEDDING = 14,
B_UNICODE_RIGHT_TO_LEFT_OVERRIDE = 15,
B_UNICODE_POP_DIRECTIONAL_FORMAT = 16,
B_UNICODE_DIR_NON_SPACING_MARK = 17,
B_UNICODE_BOUNDARY_NEUTRAL = 18,
B_UNICODE_DIRECTION_COUNT
};
/**
* Script range as defined in the Unicode standard.
*/
enum unicode_char_script {
// Script names
B_UNICODE_BASIC_LATIN,
B_UNICODE_LATIN_1_SUPPLEMENT,
B_UNICODE_LATIN_EXTENDED_A,
B_UNICODE_LATIN_EXTENDED_B,
B_UNICODE_IPA_EXTENSIONS,
B_UNICODE_SPACING_MODIFIER_LETTERS,
B_UNICODE_COMBINING_DIACRITICAL_MARKS,
B_UNICODE_GREEK,
B_UNICODE_CYRILLIC,
B_UNICODE_ARMENIAN,
B_UNICODE_HEBREW,
B_UNICODE_ARABIC,
B_UNICODE_SYRIAC,
B_UNICODE_THAANA,
B_UNICODE_DEVANAGARI,
B_UNICODE_BENGALI,
B_UNICODE_GURMUKHI,
B_UNICODE_GUJARATI,
B_UNICODE_ORIYA,
B_UNICODE_TAMIL,
B_UNICODE_TELUGU,
B_UNICODE_KANNADA,
B_UNICODE_MALAYALAM,
B_UNICODE_SINHALA,
B_UNICODE_THAI,
B_UNICODE_LAO,
B_UNICODE_TIBETAN,
B_UNICODE_MYANMAR,
B_UNICODE_GEORGIAN,
B_UNICODE_HANGUL_JAMO,
B_UNICODE_ETHIOPIC,
B_UNICODE_CHEROKEE,
B_UNICODE_UNIFIED_CANADIAN_ABORIGINAL_SYLLABICS,
B_UNICODE_OGHAM,
B_UNICODE_RUNIC,
B_UNICODE_KHMER,
B_UNICODE_MONGOLIAN,
B_UNICODE_LATIN_EXTENDED_ADDITIONAL,
B_UNICODE_GREEK_EXTENDED,
B_UNICODE_GENERAL_PUNCTUATION,
B_UNICODE_SUPERSCRIPTS_AND_SUBSCRIPTS,
B_UNICODE_CURRENCY_SYMBOLS,
B_UNICODE_COMBINING_MARKS_FOR_SYMBOLS,
B_UNICODE_LETTERLIKE_SYMBOLS,
B_UNICODE_NUMBER_FORMS,
B_UNICODE_ARROWS,
B_UNICODE_MATHEMATICAL_OPERATORS,
B_UNICODE_MISCELLANEOUS_TECHNICAL,
B_UNICODE_CONTROL_PICTURES,
B_UNICODE_OPTICAL_CHARACTER_RECOGNITION,
B_UNICODE_ENCLOSED_ALPHANUMERICS,
B_UNICODE_BOX_DRAWING,
B_UNICODE_BLOCK_ELEMENTS,
B_UNICODE_GEOMETRIC_SHAPES,
B_UNICODE_MISCELLANEOUS_SYMBOLS,
B_UNICODE_DINGBATS,
B_UNICODE_BRAILLE_PATTERNS,
B_UNICODE_CJK_RADICALS_SUPPLEMENT,
B_UNICODE_KANGXI_RADICALS,
B_UNICODE_IDEOGRAPHIC_DESCRIPTION_CHARACTERS,
B_UNICODE_CJK_SYMBOLS_AND_PUNCTUATION,
B_UNICODE_HIRAGANA,
B_UNICODE_KATAKANA,
B_UNICODE_BOPOMOFO,
B_UNICODE_HANGUL_COMPATIBILITY_JAMO,
B_UNICODE_KANBUN,
B_UNICODE_BOPOMOFO_EXTENDED,
B_UNICODE_ENCLOSED_CJK_LETTERS_AND_MONTHS,
B_UNICODE_CJK_COMPATIBILITY,
B_UNICODE_CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A,
B_UNICODE_CJK_UNIFIED_IDEOGRAPHS,
B_UNICODE_YI_SYLLABLES,
B_UNICODE_YI_RADICALS,
B_UNICODE_HANGUL_SYLLABLES,
B_UNICODE_HIGH_SURROGATES,
B_UNICODE_HIGH_PRIVATE_USE_SURROGATES,
B_UNICODE_LOW_SURROGATES,
B_UNICODE_PRIVATE_USE_AREA,
B_UNICODE_CJK_COMPATIBILITY_IDEOGRAPHS,
B_UNICODE_ALPHABETIC_PRESENTATION_FORMS,
B_UNICODE_ARABIC_PRESENTATION_FORMS_A,
B_UNICODE_COMBINING_HALF_MARKS,
B_UNICODE_CJK_COMPATIBILITY_FORMS,
B_UNICODE_SMALL_FORM_VARIANTS,
B_UNICODE_ARABIC_PRESENTATION_FORMS_B,
B_UNICODE_SPECIALS,
B_UNICODE_HALFWIDTH_AND_FULLWIDTH_FORMS,
B_UNICODE_SCRIPT_COUNT,
B_UNICODE_NO_SCRIPT = B_UNICODE_SCRIPT_COUNT
};
/**
* Values returned by the u_getCellWidth() function.
*/
enum unicode_cell_width
{
B_UNICODE_ZERO_WIDTH = 0,
B_UNICODE_HALF_WIDTH = 1,
B_UNICODE_FULL_WIDTH = 2,
B_UNICODE_NEUTRAL_WIDTH = 3,
B_UNICODE_CELL_WIDTH_COUNT
};
class _IMPEXP_LOCALE BUnicodeChar {
public:
static bool IsAlpha(uint32 c);
static bool IsAlNum(uint32 c);
static bool IsDigit(uint32 c);
static bool IsHexDigit(uint32 c);
static bool IsUpper(uint32 c);
static bool IsLower(uint32 c);
static bool IsSpace(uint32 c);
static bool IsWhitespace(uint32 c);
static bool IsControl(uint32 c);
static bool IsPunctuation(uint32 c);
static bool IsPrintable(uint32 c);
static bool IsTitle(uint32 c);
static bool IsDefined(uint32 c);
static bool IsBase(uint32 c);
static int8 Type(uint32 c);
static uint32 ToLower(uint32 c);
static uint32 ToUpper(uint32 c);
static uint32 ToTitle(uint32 c);
static int32 DigitValue(uint32 c);
static void ToUTF8(uint32 c, char **out);
static uint32 FromUTF8(const char **in);
static uint32 FromUTF8(const char *in);
static size_t UTF8StringLength(const char *str);
static size_t UTF8StringLength(const char *str, size_t maxLength);
private:
BUnicodeChar();
};
inline uint32
BUnicodeChar::FromUTF8(const char *in)
{
const char *string = in;
return FromUTF8(&string);
}
#endif /* _UNICODE_CHAR_H_ */

86
headers/posix/langinfo.h Normal file
View File

@ -0,0 +1,86 @@
#ifndef _LANGINFO_H_
#define _LANGINFO_H_
#include <LocaleBuild.h>
#include <LocaleStrings.h>
#include <nl_types.h>
#define CODESET B_CODESET /* codeset name */
#define D_T_FMT B_DATE_TIME_FORMAT /* string for formatting date and time */
#define D_FMT B_DATE_FORMAT /* date format string */
#define T_FMT B_TIME_FORMAT /* time format string */
#define T_FMT_AMPM B_AM_PM_TIME_FORMAT /* a.m. or p.m. time formatting string */
#define AM_STR B_AM_STRING /* Ante Meridian affix */
#define PM_STR B_PM_STRING /* Post Meridian affix */
/* week day names */
#define DAY_1 B_DAY_1
#define DAY_2 B_DAY_2
#define DAY_3 B_DAY_3
#define DAY_4 B_DAY_4
#define DAY_5 B_DAY_5
#define DAY_6 B_DAY_6
#define DAY_7 B_DAY_7
/* abbreviated week day names */
#define ABDAY_1 B_AB_DAY_1
#define ABDAY_2 B_AB_DAY_2
#define ABDAY_3 B_AB_DAY_3
#define ABDAY_4 B_AB_DAY_4
#define ABDAY_5 B_AB_DAY_5
#define ABDAY_6 B_AB_DAY_6
#define ABDAY_7 B_AB_DAY_7
/* month names */
#define MON_1 B_MON_1
#define MON_2 B_MON_2
#define MON_3 B_MON_3
#define MON_4 B_MON_4
#define MON_5 B_MON_5
#define MON_6 B_MON_6
#define MON_7 B_MON_7
#define MON_8 B_MON_8
#define MON_9 B_MON_9
#define MON_10 B_MON_10
#define MON_11 B_MON_11
#define MON_12 B_MON_12
/* abbreviated month names */
#define ABMON_1 B_AB_MON_1
#define ABMON_2 B_AB_MON_2
#define ABMON_3 B_AB_MON_3
#define ABMON_4 B_AB_MON_4
#define ABMON_5 B_AB_MON_5
#define ABMON_6 B_AB_MON_6
#define ABMON_7 B_AB_MON_7
#define ABMON_8 B_AB_MON_8
#define ABMON_9 B_AB_MON_9
#define ABMON_10 B_AB_MON_10
#define ABMON_11 B_AB_MON_11
#define ABMON_12 B_AB_MON_12
#define ERA B_ERA /* era description segments */
#define ERA_D_FMT B_ERA_DATE_FORMAT /* era date format string */
#define ERA_D_T_FMT B_ERA_DATE_TIME_FORMAT /* era date and time format string */
#define ERA_T_FMT B_TIME_FORMAT /* era time format string */
#define ALT_DIGITS B_ALT_DIGITS /* alternative symbols for digits */
#define RADIXCHAR B_DECIMAL_POINT /* radix char */
#define THOUSEP B_THOUSANDS_SEPARATOR /* separator for thousands */
#define YESEXPR B_YES_EXPRESSION /* affirmative response expression */
#define NOEXPR B_NO_EXPRESSION /* negative response expression */
#define YESSTR B_YES_STRING /* affirmative response for yes/no queries */
#define NOSTR B_NO_STRING /* negative response for yes/no queries */
#define CRNCYSTR B_CURRENCY_SYMBOL /* currency symbol */
//#define D_MD_ORDER 57 /* month/day order (local extension) */
#ifdef __cplusplus
extern "C"
#endif
_IMPEXP_LOCALE char *nl_langinfo(nl_item);
#endif /* _LANGINFO_H_ */

19
headers/posix/monetary.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef _MONETARY_H_
#define _MONETARY_H_
#include <stdarg.h>
#include <LocaleBuild.h>
#ifdef __cplusplus
extern "C" {
#endif
_IMPEXP_LOCALE ssize_t strfmon(char *string, size_t maxSize, const char *format, ...);
_IMPEXP_LOCALE ssize_t vstrfmon(char *string, size_t maxSize, const char *format, va_list args);
#ifdef __cplusplus
}
#endif
#endif /* _MONETARY_H_ */

View File

@ -0,0 +1,23 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#ifndef PROPERTY_FILE_H
#define PROPERTY_FILE_H
#include <File.h>
// This is the read-only version of the PropertyFile class - the
// genprops tool contains the write-only version of it
class PropertyFile : public BFile {
public:
status_t SetTo(const char *directory, const char *name);
off_t Size();
};
#endif /* PROPERTY_FILE_H */

View File

@ -0,0 +1,25 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#ifndef _UNICODE_PROPERTIES_H_
#define _UNICODE_PROPERTIES_H_
#include <SupportDefs.h>
#include <ByteOrder.h>
#define PROPERTIES_DIRECTORY "locale"
#define PROPERTIES_FILE_NAME "unicode.properties"
#define PROPERTIES_FORMAT 'UPro'
typedef struct {
uint8 size;
uint8 isBigEndian;
uint32 format;
uint8 version[3];
} UnicodePropertiesHeader;
#endif /* _UNICODE_PROPERTIES_H_ */

View File

@ -0,0 +1,4 @@
SubDir LOCALE_TOP add-ons ;
SubInclude LOCALE_TOP add-ons catalogs ;
SubInclude LOCALE_TOP add-ons collators ;

View File

@ -0,0 +1,3 @@
SubDir LOCALE_TOP add-ons catalogs ;
SubInclude LOCALE_TOP add-ons catalogs zeta ;

View File

@ -0,0 +1,89 @@
/*
** Copyright 2003, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <syslog.h>
#include <Application.h>
#include <Directory.h>
#include <File.h>
#include <FindDirectory.h>
#include <Message.h>
#include <Path.h>
#include <Roster.h>
#include <Catalog.h>
#include <LocaleRoster.h>
/** This implements a compatibility catalog-type which uses the catalogs
* supplied by the Zeta Locale Kit.
*/
class ZetaCatalog : public BCatalogAddOn {
public:
ZetaCatalog(const char *signature, const char *language,
int32 fingerprint);
~ZetaCatalog();
const char *GetString(const char *string, const char *context=NULL,
const char *comment=NULL);
const char *GetString(uint32 id);
private:
};
ZetaCatalog::ZetaCatalog(const char *signature, const char *language,
int32 fingerprint)
:
BCatalogAddOn(signature, language, fingerprint)
{
app_info appInfo;
be_app->GetAppInfo(&appInfo);
node_ref nref;
nref.device = appInfo.ref.device;
nref.node = appInfo.ref.directory;
BDirectory appDir( &nref);
// ToDo: implement loading of zeta-catalog
fInitCheck = EOPNOTSUPP;
log_team(LOG_DEBUG,
"trying to load zeta-catalog with sig %s for lang %s results in %s",
signature, language, strerror(fInitCheck));
}
ZetaCatalog::~ZetaCatalog()
{
}
const char *
ZetaCatalog::GetString(const char *string, const char *context,
const char *comment)
{
return "zeta-string-by-string";
}
const char *
ZetaCatalog::GetString(uint32 id)
{
return "zeta-string-by-id";
}
extern "C" BCatalogAddOn *
instantiate_catalog(const char *signature, const char *language, int32 fingerprint)
{
ZetaCatalog *catalog = new ZetaCatalog(signature, language, fingerprint);
if (catalog && catalog->InitCheck() != B_OK) {
delete catalog;
return NULL;
}
return catalog;
}
uint8 gCatalogAddOnPriority = 5;
// priority for Zeta catalog-add-on

View File

@ -0,0 +1,3 @@
SubDir LOCALE_TOP add-ons catalogs zeta ;
AddOn zeta : Catalog.cpp : be liblocale.so ;

View File

@ -0,0 +1,272 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <Collator.h>
#include <UnicodeChar.h>
#include <String.h>
#include <Message.h>
#include <ctype.h>
struct compare_context {
compare_context(bool ignorePunctuation)
:
inputA(ignorePunctuation),
inputB(ignorePunctuation)
{
}
typedef BCollatorAddOn::input_context input_context;
const char *a;
const char *b;
input_context inputA;
input_context inputB;
size_t length;
};
class FrenchCollator : public BCollatorAddOn {
public:
FrenchCollator();
FrenchCollator(BMessage *archive);
~FrenchCollator();
virtual status_t GetSortKey(const char *string, BString *key, int8 strength,
bool ignorePunctuation);
virtual int Compare(const char *a, const char *b, int32 length, int8 strength,
bool ignorePunctuation);
// (un-)archiving API
virtual status_t Archive(BMessage *archive, bool deep) const;
static BArchivable *Instantiate(BMessage *archive);
private:
int CompareSecondary(compare_context &context);
typedef BCollatorAddOn _inherited;
};
static const char *kSignature = "application/x-vnd.locale-collator.french";
inline char
uint32_to_char(uint32 c)
{
if (c > 255)
return 255;
return (char)c;
}
// #pragma mark -
FrenchCollator::FrenchCollator()
{
}
FrenchCollator::FrenchCollator(BMessage *archive)
: BCollatorAddOn(archive)
{
}
FrenchCollator::~FrenchCollator()
{
}
int
FrenchCollator::CompareSecondary(compare_context &context)
{
if (context.length-- <= 0)
return 0;
uint32 charA = BUnicodeChar::ToLower(GetNextChar(&context.a, context.inputA));
uint32 charB = BUnicodeChar::ToLower(GetNextChar(&context.b, context.inputB));
// the two strings does have the same size when we get here
// (unfortunately, "length" is specified in bytes, not characters [if it was -1])
if (charA == 0)
return 0;
int compare = CompareSecondary(context);
if (compare != 0)
return compare;
return (int32)charA - (int32)charB;
}
status_t
FrenchCollator::GetSortKey(const char *string, BString *key, int8 strength,
bool ignorePunctuation)
{
if (strength == B_COLLATE_PRIMARY)
return _inherited::GetSortKey(string, key, strength, ignorePunctuation);
size_t length = strlen(string);
if (strength > B_COLLATE_QUATERNARY) {
key->SetTo(string, length);
return B_OK;
// what can we do about that?
}
if (strength >= B_COLLATE_QUATERNARY) {
// the difference between tertiary and quaternary collation strength
// are usually a different handling of punctuation characters
ignorePunctuation = false;
}
size_t keyLength = PrimaryKeyLength(length) + length + 1;
// the primary key + the secondary key + separator char
if (strength != B_COLLATE_SECONDARY) {
keyLength += length + 1;
// the secondary key + the tertiary key + separator char
}
char *begin = key->LockBuffer(keyLength);
if (begin == NULL)
return B_NO_MEMORY;
char *buffer = PutPrimaryKey(string, begin, length, ignorePunctuation);
*buffer++ = '\01';
// separator
char *secondary = buffer;
input_context context(ignorePunctuation);
const char *source = string;
uint32 c;
for (uint32 i = 0; (c = GetNextChar(&source, context)) && i < length; i++) {
*buffer++ = uint32_to_char(BUnicodeChar::ToLower(c));
// we only support Latin-1 characters here
// ToDo: this creates a non UTF-8 sort key - is that what we want?
}
// reverse key
char *end = buffer - 1;
while (secondary < end) {
char c = secondary[0];
*secondary++ = end[0];
*end-- = c;
}
// apply tertiary collation if necessary
if (strength != B_COLLATE_SECONDARY) {
*buffer++ = '\01';
// separator
input_context context(ignorePunctuation);
source = string;
uint32 c;
for (uint32 i = 0; (c = GetNextChar(&source, context)) && i < length; i++) {
// ToDo: same problem as above, no UTF-8 key
if (BUnicodeChar::IsLower(c))
*buffer++ = uint32_to_char(BUnicodeChar::ToUpper(c));
else
*buffer++ = uint32_to_char(BUnicodeChar::ToLower(c));
}
}
*buffer = '\0';
key->UnlockBuffer(buffer - begin);
return B_OK;
}
int
FrenchCollator::Compare(const char *a, const char *b, int32 length, int8 strength,
bool ignorePunctuation)
{
int compare = _inherited::Compare(a, b, length, B_COLLATE_PRIMARY, ignorePunctuation);
if (strength == B_COLLATE_PRIMARY || compare != 0)
return compare;
else if (strength >= B_COLLATE_QUATERNARY) {
// the difference between tertiary and quaternary collation strength
// are usually a different handling of punctuation characters
ignorePunctuation = false;
}
compare_context context(ignorePunctuation);
context.a = a;
context.b = b;
context.length = length;
switch (strength) {
case B_COLLATE_SECONDARY:
return CompareSecondary(context);
case B_COLLATE_TERTIARY:
case B_COLLATE_QUATERNARY:
{
// diacriticals can only change the order between equal strings
int32 compare = Compare(a, b, length, B_COLLATE_SECONDARY, ignorePunctuation);
if (compare != 0)
return compare;
for (int32 i = 0; i < length; i++) {
uint32 charA = GetNextChar(&a, context.inputA);
uint32 charB = GetNextChar(&b, context.inputB);
// the two strings does have the same size when we get here
if (charA == 0)
return 0;
if (charA != charB)
return (int32)charB - (int32)charA;
}
return 0;
}
case B_COLLATE_IDENTICAL:
default:
return strncmp(a, b, length);
}
}
status_t
FrenchCollator::Archive(BMessage *archive, bool deep) const
{
status_t status = BArchivable::Archive(archive, deep);
// add the add-on signature, so that the roster can load
// us on demand!
if (status == B_OK)
status = archive->AddString("add_on", kSignature);
return status;
}
BArchivable *
FrenchCollator::Instantiate(BMessage *archive)
{
if (validate_instantiation(archive, "FrenchCollator"))
return new FrenchCollator(archive);
return NULL;
}
// #pragma mark -
extern "C" BCollatorAddOn *
instantiate_collator(void)
{
return new FrenchCollator();
}

View File

@ -0,0 +1,131 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <Collator.h>
#include <UnicodeChar.h>
#include <String.h>
#include <Message.h>
#include <ctype.h>
/** This implements a German DIN-2 collator. It replaces German umlauts
* like "ä" with "ae", or "ö" with "oe", etc.
* For all other characters, it does the same as its parent class,
* BCollatorAddOn.
* This method is intended for sorting names (while DIN-1 is intended
* for words, BCollatorAddOn is already compatible with that method).
* It is used in German telephone books, for example.
*/
class CollatorDeutsch : public BCollatorAddOn {
public:
CollatorDeutsch();
CollatorDeutsch(BMessage *archive);
~CollatorDeutsch();
// (un-)archiving API
virtual status_t Archive(BMessage *archive, bool deep) const;
static BArchivable *Instantiate(BMessage *archive);
protected:
virtual uint32 GetNextChar(const char **string, input_context &context);
};
static const char *kSignature = "application/x-vnd.locale-collator.germanDIN-2";
CollatorDeutsch::CollatorDeutsch()
{
}
CollatorDeutsch::CollatorDeutsch(BMessage *archive)
: BCollatorAddOn(archive)
{
}
CollatorDeutsch::~CollatorDeutsch()
{
}
uint32
CollatorDeutsch::GetNextChar(const char **string, input_context &context)
{
uint32 c = context.next_char;
if (c != 0) {
context.next_char = 0;
return c;
}
do {
c = BUnicodeChar::FromUTF8(string);
} while (context.ignore_punctuation
&& (BUnicodeChar::IsPunctuation(c) || BUnicodeChar::IsSpace(c)));
switch (c) {
case 223: // ß
context.next_char = 's';
return 's';
case 196: // Ae
context.next_char = 'e';
return 'A';
case 214: // Oe
context.next_char = 'e';
return 'O';
case 220: // Ue
context.next_char = 'e';
return 'U';
case 228: // ae
context.next_char = 'e';
return 'a';
case 246: // oe
context.next_char = 'e';
return 'o';
case 252: // ue
context.next_char = 'e';
return 'u';
}
return c;
}
status_t
CollatorDeutsch::Archive(BMessage *archive, bool deep) const
{
status_t status = BArchivable::Archive(archive, deep);
// add the add-on signature, so that the roster can load
// us on demand!
if (status == B_OK)
status = archive->AddString("add_on", kSignature);
return status;
}
BArchivable *
CollatorDeutsch::Instantiate(BMessage *archive)
{
if (validate_instantiation(archive, "CollatorDeutsch"))
return new CollatorDeutsch(archive);
return NULL;
}
// #pragma mark -
extern "C" BCollatorAddOn *
instantiate_collator(void)
{
return new CollatorDeutsch();
}

View File

@ -0,0 +1,15 @@
SubDir LOCALE_TOP add-ons collators ;
rule Collator
{
# Collator <sources> ;
local sources = $(1) ;
local name = $(sources[1]:B) ;
local rsrc = $(name:S=.rsrc) ;
AddResources $(name) : $(rsrc) ;
AddOn $(name) : $(sources) : be liblocale.so ;
}
Collator GermanDIN-2.cpp ;
Collator French.cpp ;

10
src/bin/locale/Jamfile Normal file
View File

@ -0,0 +1,10 @@
SubDir LOCALE_TOP apps ;
AddResources collectcatkeys : collectcatkeys.rsrc ;
Application collectcatkeys : collectcatkeys.cpp RegExp.cpp : be liblocale.so ;
AddResources linkcatkeys : linkcatkeys.rsrc ;
Application linkcatkeys : linkcatkeys.cpp : be liblocale.so ;
AddResources dumpcatalog ;
Application dumpcatalog : dumpcatalog.cpp : be liblocale.so ;

View File

@ -0,0 +1,277 @@
/*
** Copyright 2003, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <cctype>
#include <cerrno>
#include <cstdio>
#include <cstdlib>
#include <Catalog.h>
using namespace BPrivate;
#include <Entry.h>
#include <File.h>
#include "RegExp.h"
#include <String.h>
bool showKeys = false;
bool showSummary = false;
bool showWarnings = false;
const char *inputFile = NULL;
BString outputFile;
const char *catalogSig = NULL;
const char *catalogLang = "English";
BString rxString("be_catalog\\s*->\\s*GetString\\s*");
BString str, ctx, cmt;
bool haveID;
int32 id;
EditableCatalog *catalog = NULL;
void
usage()
{
fprintf(stderr,
"usage: collectcatkeys [-pvw] [-r <regex>] [-o <outfile>] [-l <catalogLanguage>]\n"
" -s <catalogSig> <prepCppFile>\n"
"options:\n"
" -l <catalogLang>\tlanguage of the target-catalog (default is English)\n"
" -o <outfile>\t\texplicitly specifies the name of the output-file\n"
" -p\t\t\tprint keys as they are found\n"
" -r <regex>\t\tchanges the regex used by the key-scanner to the one given,\n"
" \t\t\tthe default is: be_catalog\\s*->\\s*GetString\\s*\n"
" -s <catalogSig>\tsignature of the target-catalog\n"
" -v\t\t\tbe verbose, show summary\n"
" -w\t\t\tshow warnings about catalog-accesses that couldn't be resolved completely\n");
exit(-1);
}
bool
fetchStr(const char *&in, BString &str, bool lookForID)
{
int parLevel = 0;
while(isspace(*in) || *in == '(') {
if (*in == '(')
parLevel++;
in++;
}
if (*in == '"') {
in++;
bool quoted = false;
while (*in != '"' || quoted) {
if (quoted) {
if (*in == 'n')
str.Append("\n",1);
else if (*in == 't')
str.Append("\t",1);
else if (*in == '"')
str.Append("\"",1);
else
// dump quote from unknown quoting-sequence:
str.Append(in,1);
quoted = false;
} else {
quoted = (*in == '\\');
if (!quoted)
str.Append(in,1);
}
in++;
}
in++;
} else if (!memcmp(in, "__null", 6)) {
// NULL is preprocessed into __null, which we parse as ""
in += 6;
} else if (lookForID && (isdigit(*in) || *in == '-' || *in == '+')) {
// try to parse an ID (a long):
errno = 0;
char *next;
id = strtol(in, &next, 10);
if (id != 0 || errno == 0) {
haveID = true;
in = next;
}
} else
return false;
while(isspace(*in) || *in == ')') {
if (*in == ')') {
if (!parLevel)
return true;
parLevel--;
}
in++;
}
return true;
}
bool
fetchKey(const char *&in)
{
str = ctx = cmt = "";
haveID = false;
// fetch native string or id:
if (!fetchStr(in, str, true))
return false;
if (*in == ',') {
in++;
// fetch context:
if (!fetchStr(in, ctx, false))
return false;
if (*in == ',') {
in++;
// fetch comment:
if (!fetchStr(in, cmt, false))
return false;
}
}
return true;
}
void
collectAllCatalogKeys(BString& inputStr)
{
RegExp rx;
struct regexp *rxprg = rx.Compile(rxString.String());
if (rx.InitCheck() != B_OK) {
fprintf(stderr, "regex-compilation error %s\n", rx.ErrorString());
return;
}
status_t res;
const char *in = inputStr.String();
while(rx.RunMatcher(rxprg, in)) {
const char *start = rxprg->startp[0];
in = rxprg->endp[0];
if (fetchKey(in)) {
if (haveID) {
if (showKeys)
printf("CatKey(%ld)\n", id);
res = catalog->SetString(id, "");
if (res != B_OK) {
fprintf(stderr, "couldn't add key %ld - error: %s\n",
id, strerror(res));
exit(-1);
}
} else {
if (showKeys)
printf("CatKey(\"%s\", \"%s\", \"%s\")\n", str.String(),
ctx.String(), cmt.String());
res = catalog->SetString(str.String(), str.String(), ctx.String(), cmt.String());
if (res != B_OK) {
fprintf(stderr, "couldn't add key %s,%s,%s - error: %s\n",
str.String(), ctx.String(), cmt.String(), strerror(res));
exit(-1);
}
}
} else if (showWarnings) {
const char *end = strchr(in, ';');
BString match;
if (end)
match.SetTo(start, end-start+1);
else
// can't determine end of statement, we output next 40 characters
match.SetTo(start, 40);
fprintf(stderr, "Warning: couldn't resolve catalog-access:\n\t%s\n",
match.String());
}
}
}
int
main(int argc, char **argv)
{
while ((++argv)[0]) {
if (argv[0][0] == '-' && argv[0][1] != '-') {
char *arg = argv[0] + 1;
char c;
while ((c = *arg++) != '\0') {
if (c == 'p')
showKeys = true;
else if (c == 'l')
catalogLang = (++argv)[0];
else if (c == 's')
catalogSig = (++argv)[0];
else if (c == 'v')
showSummary = true;
else if (c == 'w')
showWarnings = true;
else if (c == 'o') {
outputFile = (++argv)[0];
break;
}
else if (c == 'r') {
rxString = (++argv)[0];
break;
}
}
} else if (!strcmp(argv[0], "--help")) {
usage();
} else {
if (!inputFile)
inputFile = argv[0];
else
usage();
}
}
if (!outputFile.Length() && inputFile) {
// generate default output-file from input-file by replacing
// the extension with '.catkeys':
outputFile = inputFile;
int32 dot = outputFile.FindLast('.');
if (dot >= B_OK)
outputFile.Truncate(dot);
outputFile << ".catkeys";
}
if (!inputFile || !catalogSig || !outputFile.Length() || !catalogLang)
usage();
BFile inFile;
status_t res = inFile.SetTo(inputFile, B_READ_ONLY);
if (res != B_OK) {
fprintf(stderr, "unable to open inputfile %s - error: %s\n", inputFile,
strerror(res));
exit(-1);
}
off_t sz;
inFile.GetSize(&sz);
if (sz > 0) {
BString inputStr;
char *buf = inputStr.LockBuffer(sz);
off_t rsz = inFile.Read(buf, sz);
if (rsz < sz) {
fprintf(stderr, "couldn't read %Ld bytes from %s (got only %Ld)\n",
sz, inputFile, rsz);
exit(-1);
}
inputStr.UnlockBuffer(rsz);
catalog = new EditableCatalog("Default", catalogSig, catalogLang);
collectAllCatalogKeys(inputStr);
res = catalog->WriteToFile(outputFile.String());
if (res != B_OK) {
fprintf(stderr, "couldn't write catalog to %s - error: %s\n",
outputFile.String(), strerror(res));
exit(-1);
}
if (showSummary) {
int32 count = catalog->CountItems();
if (count)
fprintf(stderr, "%ld key%s found and written to %s\n",
count, (count==1 ? "": "s"), outputFile.String());
else
fprintf(stderr, "no keys found\n");
}
delete catalog;
}
// BEntry inEntry(inputFile);
// inEntry.Remove();
return res;
}

View File

@ -0,0 +1,76 @@
/*
** Copyright 2003, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <cstdio>
#include <cstdlib>
#include <Catalog.h>
#include <DefaultCatalog.h>
#include <File.h>
#include <String.h>
void
usage()
{
fprintf(stderr, "usage: dumpcatalog <catalogFiles>\n");
exit(-1);
}
int
main(int argc, char **argv)
{
const char *inputFile = NULL;
status_t res;
if (!argv[1] || !strcmp(argv[1], "--help")) {
usage();
} else {
inputFile = argv[1];
}
if (!inputFile || !strlen(inputFile))
usage();
EditableCatalog inputCatalog("Default", "dummy", "dummy");
if ((res = inputCatalog.InitCheck()) != B_OK) {
fprintf(stderr, "couldn't construct catalog %s - error: %s\n",
inputFile, strerror(res));
exit(-1);
}
if ((res = inputCatalog.ReadFromFile(inputFile)) != B_OK) {
fprintf(stderr, "couldn't load input-catalog %s - error: %s\n",
inputFile, strerror(res));
exit(-1);
}
DefaultCatalog* inputCatImpl
= dynamic_cast<DefaultCatalog*>(inputCatalog.CatalogAddOn());
if (!inputCatImpl) {
fprintf(stderr, "couldn't access impl of input-catalog %s\n",
inputFile);
exit(-1);
}
// now walk over all entries in input-catalog and dump them to
// stdout
DefaultCatalog::CatWalker walker;
if ((res = inputCatImpl->GetWalker(&walker)) != B_OK) {
fprintf(stderr, "couldn't get walker for input-catalog %s - error: %s\n",
inputFile, strerror(res));
exit(-1);
}
BString str, ctx, cmt;
while(!walker.AtEnd()) {
const CatKey &key(walker.GetKey());
key.GetStringParts(&str, &ctx, &cmt);
printf("Hash:\t\t%ld\nKey:\t\t<%s:%s:%s>\nTranslation:\t%s\n-----\n",
key.fHashVal, str.String(), ctx.String(), cmt.String(),
walker.GetValue());
walker.Next();
}
int32 count = inputCatalog.CountItems();
if (count)
fprintf(stderr, "%ld entr%s dumped\n", count, (count==1 ? "y": "ies"));
else
fprintf(stderr, "no entries found\n");
return res;
}

View File

@ -0,0 +1,174 @@
/*
** Copyright 2003, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <Catalog.h>
#include <DefaultCatalog.h>
#include <Entry.h>
#include <File.h>
#include <String.h>
void
usage()
{
fprintf(stderr,
"usage: linkcatkeys [-v] [-t(a|f|r)] [-o <outfile>] [-l <catalogLang>]\n"
" -s <catalogSig> <catalogFiles>\n"
"options:\n"
" -l <catalogLang>\tlanguage of the target-catalog (default is English)\n"
" -o <outfile>\t\texplicitly specifies the name of the output-file\n"
" -s <catalogSig>\tsignature of the target-catalog\n"
" -t(a|f|r)\t\tspecifies target of resulting catalog (-tf is default)\n"
" \t\ta => write catalog as an attribute (to output-file)\n"
" \t\tf => write catalog into the output-file\n"
" \t\tr => write catalog as a resource (to output-file)\n"
" -v\t\t\tbe verbose, show summary\n");
exit(-1);
}
int
main(int argc, char **argv)
{
bool showSummary = false;
bool showWarnings = false;
vector<const char *> inputFiles;
BString outputFile("default.catalog");
enum TargetType {
TARGET_ATTRIBUTE,
TARGET_FILE,
TARGET_RESOURCE
};
TargetType outputTarget = TARGET_FILE;
const char *catalogSig = NULL;
const char *catalogLang = "English";
status_t res;
while ((++argv)[0]) {
if (argv[0][0] == '-' && argv[0][1] != '-') {
char *arg = argv[0] + 1;
char c;
while ((c = *arg++) != '\0') {
if (c == 's')
catalogSig = (++argv)[0];
else if (c == 'v')
showSummary = true;
else if (c == 'w')
showWarnings = true;
else if (c == 'o') {
outputFile = (++argv)[0];
break;
}
else if (c == 't') {
switch(*arg) {
case 'a': outputTarget = TARGET_ATTRIBUTE; break;
case 'f': outputTarget = TARGET_FILE; break;
case 'r': outputTarget = TARGET_RESOURCE; break;
default: usage();
}
}
}
} else if (!strcmp(argv[0], "--help")) {
usage();
} else {
inputFiles.push_back(argv[0]);
}
}
if (inputFiles.empty() || !catalogSig || !outputFile.Length())
usage();
EditableCatalog targetCatalog("Default", catalogSig, catalogLang);
if ((res = targetCatalog.InitCheck()) != B_OK) {
fprintf(stderr, "couldn't construct target-catalog %s - error: %s\n",
outputFile.String(), strerror(res));
exit(-1);
}
DefaultCatalog* targetCatImpl
= dynamic_cast<DefaultCatalog*>(targetCatalog.CatalogAddOn());
if (!targetCatImpl) {
fprintf(stderr, "couldn't access impl of target-catalog %s\n",
outputFile.String());
exit(-1);
}
uint32 count = inputFiles.size();
for( uint32 i=0; i<count; ++i) {
EditableCatalog inputCatalog("Default", catalogSig, "native");
if ((res = inputCatalog.ReadFromFile(inputFiles[i])) != B_OK) {
fprintf(stderr, "couldn't load target-catalog %s - error: %s\n",
inputFiles[i], strerror(res));
exit(-1);
}
DefaultCatalog* inputCatImpl
= dynamic_cast<DefaultCatalog*>(inputCatalog.CatalogAddOn());
if (!inputCatImpl) {
fprintf(stderr, "couldn't access impl of input-catalog %s\n",
inputFiles[i]);
exit(-1);
}
// now walk over all entries in input-catalog and add them to
// target catalog, unless they already exist there.
// (This could be improved by simply inserting the hashmaps,
// but this should be fast enough).
DefaultCatalog::CatWalker walker;
if ((res = inputCatImpl->GetWalker(&walker)) != B_OK) {
fprintf(stderr, "couldn't get walker for input-catalog %s - error: %s\n",
inputFiles[i], strerror(res));
exit(-1);
}
while(!walker.AtEnd()) {
const CatKey &key(walker.GetKey());
if (!targetCatImpl->GetString(key))
targetCatImpl->SetString(key, walker.GetValue());
walker.Next();
}
}
switch(outputTarget) {
case TARGET_ATTRIBUTE: {
BEntry entry(outputFile.String());
entry_ref eref;
entry.GetRef(&eref);
res = targetCatalog.WriteToAttribute(&eref);
if (res != B_OK) {
fprintf(stderr, "couldn't write target-attribute to %s - error: %s\n",
outputFile.String(), strerror(res));
exit(-1);
}
break;
}
case TARGET_RESOURCE: {
BEntry entry(outputFile.String());
entry_ref eref;
entry.GetRef(&eref);
res = targetCatalog.WriteToResource(&eref);
if (res != B_OK) {
fprintf(stderr, "couldn't write target-resource to %s - error: %s\n",
outputFile.String(), strerror(res));
exit(-1);
}
}
default: {
res = targetCatalog.WriteToFile(outputFile.String());
if (res != B_OK) {
fprintf(stderr, "couldn't write target-catalog to %s - error: %s\n",
outputFile.String(), strerror(res));
exit(-1);
}
}
}
if (showSummary) {
int32 count = targetCatalog.CountItems();
if (count)
fprintf(stderr, "%ld key%s found and written to %s\n",
count, (count==1 ? "": "s"), outputFile.String());
else
fprintf(stderr, "no keys found\n");
}
return res;
}

View File

@ -0,0 +1,13 @@
SubDir LOCALE_TOP languages ;
LANGUAGE_DIR = /etc/locale/languages ;
{
local languages = [ Glob $(SUBDIR) : *.language ] ;
local language ;
for language in [ FGristFiles $(languages:D=) ] {
local installedLanguage = $(language:G=installed) ;
MakeLocate $(installedLanguage) : $(LANGUAGE_DIR) ;
File $(installedLanguage) : $(language) ;
}
}

View File

@ -0,0 +1,49 @@
de,germanic,ltr
--
Gestern
Heute
Morgen
Zukunft
Sonntag
Montag
Dienstag
Mittwoch
Donnerstag
Freitag
Samstag
So
Mo
Di
Mi
Do
Fr
Sa
Januar
Februar
März
April
Mai
Juni
Juli
August
September
Oktober
November
Dezember
Jan
Feb
Mär
Apr
Mai
Jun
Jul
Aug
Sep
Okt
Nov
Dez

View File

@ -0,0 +1,49 @@
fr,roman,ltr
--
Hier
Aujourd'hui
Demain
Avenir
Dimanche
Lundi
Mardi
Mercredi
Jeudi
Vendredi
Samedi
Dim
Lun
Mar
Mer
Jeu
Ven
Sam
Janvier
Février
Mars
Avril
Mai
Juin
Juillet
Août
Septembre
Octobre
Novembre
Décembre
Jan
Fev
Mars
Avr
Mai
Juin
Juil
Août
Sep
Oct
Nov
Dec

421
src/kits/locale/Catalog.cpp Normal file
View File

@ -0,0 +1,421 @@
/*
** Distributed under the terms of the OpenBeOS License.
** Copyright 2003-2004. All rights reserved.
**
** Authors: Axel Dörfler, axeld@pinc-software.de
** Oliver Tappe, zooey@hirschkaefer.de
*/
#include <syslog.h>
#include <Application.h>
#include <Catalog.h>
#include <Locale.h>
#include <LocaleRoster.h>
#include <Node.h>
#include <Roster.h>
BCatalog* be_catalog = NULL;
// catalog used by translation macros
BCatalog* be_app_catalog = NULL;
// app-catalog (useful for accessing app's catalog from inside an add-on,
// since in an add-on, be_catalog will hold the add-on's catalog.
//#pragma mark - BCatalog
BCatalog::BCatalog()
:
fCatalog(NULL)
{
}
BCatalog::BCatalog(const char *signature, const char *language,
int32 fingerprint)
{
fCatalog = be_locale_roster->LoadCatalog(signature, language, fingerprint);
}
BCatalog::~BCatalog()
{
if (be_catalog == this)
be_app_catalog = be_catalog = NULL;
be_locale_roster->UnloadCatalog(fCatalog);
}
const char *
BCatalog::GetString(const char *string, const char *context, const char *comment)
{
const char *translated;
for (BCatalogAddOn* cat = fCatalog; cat != NULL; cat = cat->fNext) {
translated = cat->GetString(string, context, comment);
if (translated)
return translated;
}
return string;
}
const char *
BCatalog::GetString(uint32 id)
{
const char *translated;
for (BCatalogAddOn* cat = fCatalog; cat != NULL; cat = cat->fNext) {
translated = cat->GetString(id);
if (translated)
return translated;
}
return "";
}
status_t
BCatalog::GetData(const char *name, BMessage *msg)
{
if (!fCatalog)
return B_NO_INIT;
status_t res;
for (BCatalogAddOn* cat = fCatalog; cat != NULL; cat = cat->fNext) {
res = cat->GetData(name, msg);
if (res != B_NAME_NOT_FOUND && res != EOPNOTSUPP)
return res;
// return B_OK if found, or specific error-code
}
return B_NAME_NOT_FOUND;
}
status_t
BCatalog::GetData(uint32 id, BMessage *msg)
{
if (!fCatalog)
return B_NO_INIT;
status_t res;
for (BCatalogAddOn* cat = fCatalog; cat != NULL; cat = cat->fNext) {
res = cat->GetData(id, msg);
if (res != B_NAME_NOT_FOUND && res != EOPNOTSUPP)
return res;
// return B_OK if found, or specific error-code
}
return B_NAME_NOT_FOUND;
}
status_t
BCatalog::GetAppCatalog(BCatalog* catalog)
{
app_info appInfo;
if (!be_app || be_app->GetAppInfo(&appInfo) != B_OK)
return B_ENTRY_NOT_FOUND;
BString sig(appInfo.signature);
// drop supertype from mimetype (should be "application/"):
int32 pos = sig.FindFirst('/');
if (pos >= 0)
sig.Remove(0, pos+1);
// try to fetch fingerprint from app-file (attribute):
int32 fingerprint = 0;
BNode appNode(&appInfo.ref);
appNode.ReadAttr(BLocaleRoster::kCatFingerprintAttr, B_INT32_TYPE, 0,
&fingerprint, sizeof(int32));
// try to load catalog (with given fingerprint):
catalog->fCatalog
= be_locale_roster->LoadCatalog(sig.String(), NULL, fingerprint);
// load native embedded id-based catalog. If such a catalog exists,
// we can fall back to native strings for id-based access, too.
BCatalogAddOn *embeddedCatalog
= be_locale_roster->LoadEmbeddedCatalog(&appInfo.ref);
if (embeddedCatalog) {
if (!catalog->fCatalog)
// embedded catalog is the only catalog that was found:
catalog->fCatalog = embeddedCatalog;
else {
// append embedded catalog to list of loaded catalogs:
BCatalogAddOn *currCat = catalog->fCatalog;
while (currCat->fNext)
currCat = currCat->fNext;
currCat->fNext = embeddedCatalog;
}
}
// make app-catalog the current catalog for translation-macros:
be_app_catalog = be_catalog = catalog;
return catalog->InitCheck();
}
//#pragma mark - BCatalogAddOn
BCatalogAddOn::BCatalogAddOn(const char *signature, const char *language,
int32 fingerprint)
:
fInitCheck(B_NO_INIT),
fSignature(signature),
fLanguageName(language),
fFingerprint(fingerprint),
fNext(NULL)
{
fLanguageName.ToLower();
// canonicalize language-name to lowercase
}
BCatalogAddOn::~BCatalogAddOn()
{
}
void
BCatalogAddOn::UpdateFingerprint()
{
fFingerprint = 0;
// base implementation always yields the same fingerprint,
// which means that no version-mismatch detection is possible.
}
status_t
BCatalogAddOn::InitCheck() const
{
return fInitCheck;
}
bool
BCatalogAddOn::CanHaveData() const
{
return false;
}
status_t
BCatalogAddOn::GetData(const char *name, BMessage *msg)
{
return EOPNOTSUPP;
}
status_t
BCatalogAddOn::GetData(uint32 id, BMessage *msg)
{
return EOPNOTSUPP;
}
status_t
BCatalogAddOn::SetString(const char *string, const char *translated,
const char *context, const char *comment)
{
return EOPNOTSUPP;
}
status_t
BCatalogAddOn::SetString(int32 id, const char *translated)
{
return EOPNOTSUPP;
}
bool
BCatalogAddOn::CanWriteData() const
{
return false;
}
status_t
BCatalogAddOn::SetData(const char *name, BMessage *msg)
{
return EOPNOTSUPP;
}
status_t
BCatalogAddOn::SetData(uint32 id, BMessage *msg)
{
return EOPNOTSUPP;
}
status_t
BCatalogAddOn::ReadFromFile(const char *path)
{
return EOPNOTSUPP;
}
status_t
BCatalogAddOn::ReadFromAttribute(entry_ref *appOrAddOnRef)
{
return EOPNOTSUPP;
}
status_t
BCatalogAddOn::ReadFromResource(entry_ref *appOrAddOnRef)
{
return EOPNOTSUPP;
}
status_t
BCatalogAddOn::WriteToFile(const char *path)
{
return EOPNOTSUPP;
}
status_t
BCatalogAddOn::WriteToAttribute(entry_ref *appOrAddOnRef)
{
return EOPNOTSUPP;
}
status_t
BCatalogAddOn::WriteToResource(entry_ref *appOrAddOnRef)
{
return EOPNOTSUPP;
}
void BCatalogAddOn::MakeEmpty()
{
}
int32
BCatalogAddOn::CountItems() const
{
return 0;
}
//#pragma mark - EditableCatalog
namespace BPrivate {
EditableCatalog::EditableCatalog(const char *type, const char *signature,
const char *language)
{
fCatalog = be_locale_roster->CreateCatalog(type, signature, language);
}
EditableCatalog::~EditableCatalog()
{
}
status_t
EditableCatalog::SetString(const char *string, const char *translated,
const char *context, const char *comment)
{
if (!fCatalog)
return B_NO_INIT;
return fCatalog->SetString(string, translated, context, comment);
}
status_t
EditableCatalog::SetString(int32 id, const char *translated)
{
if (!fCatalog)
return B_NO_INIT;
return fCatalog->SetString(id, translated);
}
bool
EditableCatalog::CanWriteData() const
{
if (!fCatalog)
return false;
return fCatalog->CanWriteData();
}
status_t
EditableCatalog::SetData(const char *name, BMessage *msg)
{
if (!fCatalog)
return B_NO_INIT;
return fCatalog->SetData(name, msg);
}
status_t
EditableCatalog::SetData(uint32 id, BMessage *msg)
{
if (!fCatalog)
return B_NO_INIT;
return fCatalog->SetData(id, msg);
}
status_t
EditableCatalog::ReadFromFile(const char *path)
{
if (!fCatalog)
return B_NO_INIT;
return fCatalog->ReadFromFile(path);
}
status_t
EditableCatalog::ReadFromAttribute(entry_ref *appOrAddOnRef)
{
if (!fCatalog)
return B_NO_INIT;
return fCatalog->ReadFromAttribute(appOrAddOnRef);
}
status_t
EditableCatalog::ReadFromResource(entry_ref *appOrAddOnRef)
{
if (!fCatalog)
return B_NO_INIT;
return fCatalog->ReadFromResource(appOrAddOnRef);
}
status_t
EditableCatalog::WriteToFile(const char *path)
{
if (!fCatalog)
return B_NO_INIT;
return fCatalog->WriteToFile(path);
}
status_t
EditableCatalog::WriteToAttribute(entry_ref *appOrAddOnRef)
{
if (!fCatalog)
return B_NO_INIT;
return fCatalog->WriteToAttribute(appOrAddOnRef);
}
status_t
EditableCatalog::WriteToResource(entry_ref *appOrAddOnRef)
{
if (!fCatalog)
return B_NO_INIT;
return fCatalog->WriteToResource(appOrAddOnRef);
}
void EditableCatalog::MakeEmpty()
{
if (fCatalog)
fCatalog->MakeEmpty();
}
} // namespace BPrivate

View File

@ -0,0 +1,475 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <Collator.h>
#include <UnicodeChar.h>
#include <String.h>
#include <Message.h>
#include <typeinfo>
#include <ctype.h>
// conversion array for character ranges 192 - 223 & 224 - 255
static const uint8 kNoDiacrits[] = {
'a','a','a','a','a','a','a',
'c',
'e','e','e','e',
'i','i','i','i',
240, // eth
'n',
'o','o','o','o','o',
247, //
'o',
'u','u','u','u',
'y',
254, // thorn
'y'
};
static inline uint32
getPrimaryChar(uint32 c)
{
if (c < 0x80)
return tolower(c);
// this automatically returns lowercase letters
if (c >= 192 && c < 223)
return kNoDiacrits[c - 192];
if (c == 223) // ß
return 's';
if (c >= 224 && c < 256)
return kNoDiacrits[c - 224];
return BUnicodeChar::ToLower(c);
}
BCollatorAddOn::input_context::input_context(bool ignorePunctuation)
:
ignore_punctuation(ignorePunctuation),
next_char(0),
reserved1(0),
reserved2(0)
{
}
// #pragma mark -
BCollator::BCollator()
:
fCollatorImage(B_ERROR),
fStrength(B_COLLATE_PRIMARY),
fIgnorePunctuation(true)
{
// ToDo: the collator construction will have to change; the default
// collator should be constructed by the Locale/LocaleRoster, so we
// only need a constructor where you specify all details
fCollator = new BCollatorAddOn();
}
BCollator::BCollator(BCollatorAddOn *collator, int8 strength, bool ignorePunctuation)
:
fCollator(collator),
fCollatorImage(B_ERROR),
fStrength(strength),
fIgnorePunctuation(ignorePunctuation)
{
if (collator == NULL)
fCollator = new BCollatorAddOn();
}
BCollator::BCollator(BMessage *archive)
: BArchivable(archive),
fCollator(NULL),
fCollatorImage(B_ERROR)
{
int32 data;
if (archive->FindInt32("loc:strength", &data) == B_OK)
fStrength = (uint8)data;
else
fStrength = B_COLLATE_PRIMARY;
if (archive->FindBool("loc:punctuation", &fIgnorePunctuation) != B_OK)
fIgnorePunctuation = true;
BMessage collatorArchive;
if (archive->FindMessage("loc:collator", &collatorArchive) == B_OK) {
BArchivable *unarchived = instantiate_object(&collatorArchive, &fCollatorImage);
// do we really have a BCollatorAddOn here?
fCollator = dynamic_cast<BCollatorAddOn *>(unarchived);
if (fCollator == NULL)
delete unarchived;
}
if (fCollator == NULL) {
fCollator = new BCollatorAddOn();
fCollatorImage = B_ERROR;
}
}
BCollator::~BCollator()
{
delete fCollator;
if (fCollatorImage >= B_OK)
unload_add_on(fCollatorImage);
}
void
BCollator::SetDefaultStrength(int8 strength)
{
fStrength = strength;
}
int8
BCollator::DefaultStrength() const
{
return fStrength;
}
void
BCollator::SetIgnorePunctuation(bool ignore)
{
fIgnorePunctuation = ignore;
}
bool
BCollator::IgnorePunctuation() const
{
return fIgnorePunctuation;
}
status_t
BCollator::GetSortKey(const char *string, BString *key, int8 strength)
{
if (strength == B_COLLATE_DEFAULT)
strength = fStrength;
return fCollator->GetSortKey(string, key, strength, fIgnorePunctuation);
}
int
BCollator::Compare(const char *a, const char *b, int32 length, int8 strength)
{
if (length == -1) // match the whole string
length = 0x7fffffff;
return fCollator->Compare(a, b, length,
strength == B_COLLATE_DEFAULT ? fStrength : strength, fIgnorePunctuation);
}
status_t
BCollator::Archive(BMessage *archive, bool deep) const
{
status_t status = BArchivable::Archive(archive, deep);
if (status < B_OK)
return status;
if (status == B_OK)
status = archive->AddInt32("loc:strength", fStrength);
if (status == B_OK)
status = archive->AddBool("loc:punctuation", fIgnorePunctuation);
BMessage collatorArchive;
if (status == B_OK && deep
&& typeid(*fCollator) != typeid(BCollatorAddOn)
// only archive subclasses from BCollatorAddOn
&& (status = fCollator->Archive(&collatorArchive, true)) == B_OK)
status = archive->AddMessage("loc:collator", &collatorArchive);
return status;
}
BArchivable *
BCollator::Instantiate(BMessage *archive)
{
if (validate_instantiation(archive, "BCollator"))
return new BCollator(archive);
return NULL;
}
// #pragma mark -
BCollatorAddOn::BCollatorAddOn()
{
}
BCollatorAddOn::BCollatorAddOn(BMessage *archive)
: BArchivable(archive)
{
}
BCollatorAddOn::~BCollatorAddOn()
{
}
/** This returns the next Unicode character from the UTF-8 encoded
* input string, and bumps it to the next character.
* It will ignore punctuation if specified by the context, and
* might substitute characters if needed.
*/
uint32
BCollatorAddOn::GetNextChar(const char **string, input_context &context)
{
uint32 c = context.next_char;
if (c != 0) {
context.next_char = 0;
return c;
}
do {
c = BUnicodeChar::FromUTF8(string);
} while (context.ignore_punctuation
&& (BUnicodeChar::IsPunctuation(c) || BUnicodeChar::IsSpace(c)));
if (c == 223) {
context.next_char = 's';
return 's';
}
return c;
}
/** Fills the specified buffer with the primary sort key. The buffer
* has to be long enough to hold the key.
* It returns the position in the buffer immediately after the key;
* it does not add a terminating null byte!
*/
char *
BCollatorAddOn::PutPrimaryKey(const char *string, char *buffer, int32 length,
bool ignorePunctuation)
{
input_context context(ignorePunctuation);
uint32 c;
for (int32 i = 0; (c = GetNextChar(&string, context)) != 0 && i < length; i++) {
if (c < 0x80)
*buffer++ = tolower(c);
else
BUnicodeChar::ToUTF8(getPrimaryChar(c), &buffer);
}
return buffer;
}
size_t
BCollatorAddOn::PrimaryKeyLength(size_t length)
{
return length * 2;
// the primary key needs to make space for doubled characters (like 'ß')
}
status_t
BCollatorAddOn::GetSortKey(const char *string, BString *key, int8 strength,
bool ignorePunctuation)
{
if (strength >= B_COLLATE_QUATERNARY) {
// the difference between tertiary and quaternary collation strength
// are usually a different handling of punctuation characters
ignorePunctuation = false;
}
size_t length = strlen(string);
switch (strength) {
case B_COLLATE_PRIMARY:
{
char *begin = key->LockBuffer(PrimaryKeyLength(length));
if (begin == NULL)
return B_NO_MEMORY;
char *end = PutPrimaryKey(string, begin, length, ignorePunctuation);
*end = '\0';
key->UnlockBuffer(end - begin);
break;
}
case B_COLLATE_SECONDARY:
{
char *begin = key->LockBuffer(PrimaryKeyLength(length) + length + 1);
// the primary key + the secondary key + separator char
if (begin == NULL)
return B_NO_MEMORY;
char *buffer = PutPrimaryKey(string, begin, length, ignorePunctuation);
*buffer++ = '\01';
// separator
input_context context(ignorePunctuation);
uint32 c;
for (uint32 i = 0; (c = GetNextChar(&string, context)) && i < length; i++) {
if (c < 0x80)
*buffer++ = tolower(c);
else
BUnicodeChar::ToUTF8(BUnicodeChar::ToLower(c), &buffer);
}
*buffer = '\0';
key->UnlockBuffer(buffer - begin);
break;
}
case B_COLLATE_TERTIARY:
case B_COLLATE_QUATERNARY:
{
char *begin = key->LockBuffer(PrimaryKeyLength(length) + length + 1);
// the primary key + the tertiary key + separator char
if (begin == NULL)
return B_NO_MEMORY;
char *buffer = PutPrimaryKey(string, begin, length, ignorePunctuation);
*buffer++ = '\01';
// separator
input_context context(ignorePunctuation);
uint32 c;
for (uint32 i = 0; (c = GetNextChar(&string, context)) && i < length; i++) {
BUnicodeChar::ToUTF8(c, &buffer);
}
*buffer = '\0';
key->UnlockBuffer(buffer + length - begin);
break;
}
case B_COLLATE_IDENTICAL:
default:
key->SetTo(string, length);
// is there any way to check if BString::SetTo() actually succeeded?
break;
}
return B_OK;
}
int
BCollatorAddOn::Compare(const char *a, const char *b, int32 length, int8 strength,
bool ignorePunctuation)
{
if (strength >= B_COLLATE_QUATERNARY) {
// the difference between tertiary and quaternary collation strength
// are usually a different handling of punctuation characters
ignorePunctuation = false;
}
input_context contextA(ignorePunctuation);
input_context contextB(ignorePunctuation);
switch (strength) {
case B_COLLATE_PRIMARY:
{
for (int32 i = 0; i < length; i++) {
uint32 charA = GetNextChar(&a, contextA);
uint32 charB = GetNextChar(&b, contextB);
if (charA == 0)
return charB == 0 ? 0 : -(int32)charB;
else if (charB == 0)
return (int32)charA;
charA = getPrimaryChar(charA);
charB = getPrimaryChar(charB);
if (charA != charB)
return (int32)charA - (int32)charB;
}
return 0;
}
case B_COLLATE_SECONDARY:
{
// diacriticals can only change the order between equal strings
int32 compare = Compare(a, b, length, B_COLLATE_PRIMARY, ignorePunctuation);
if (compare != 0)
return compare;
for (int32 i = 0; i < length; i++) {
uint32 charA = BUnicodeChar::ToLower(GetNextChar(&a, contextA));
uint32 charB = BUnicodeChar::ToLower(GetNextChar(&b, contextB));
// the two strings does have the same size when we get here
if (charA == 0)
return 0;
if (charA != charB)
return (int32)charA - (int32)charB;
}
return 0;
}
case B_COLLATE_TERTIARY:
case B_COLLATE_QUATERNARY:
{
// diacriticals can only change the order between equal strings
int32 compare = Compare(a, b, length, B_COLLATE_PRIMARY, ignorePunctuation);
if (compare != 0)
return compare;
for (int32 i = 0; i < length; i++) {
uint32 charA = GetNextChar(&a, contextA);
uint32 charB = GetNextChar(&b, contextB);
// the two strings does have the same size when we get here
if (charA == 0)
return 0;
if (charA != charB)
return (int32)charA - (int32)charB;
}
return 0;
}
case B_COLLATE_IDENTICAL:
default:
return strncmp(a, b, length);
}
}
status_t
BCollatorAddOn::Archive(BMessage *archive, bool deep) const
{
return BArchivable::Archive(archive, deep);
}
BArchivable *
BCollatorAddOn::Instantiate(BMessage *archive)
{
if (validate_instantiation(archive, "BCollatorAddOn"))
return new BCollatorAddOn(archive);
return NULL;
}

261
src/kits/locale/Country.cpp Normal file
View File

@ -0,0 +1,261 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <Country.h>
#include <String.h>
#include <monetary.h>
#include <stdarg.h>
const char *gStrings[] = {
// date/time format
"",
"",
"",
"",
// short date/time format
"",
"",
"",
"",
// am/pm string
"AM",
"PM",
// separators
".",
":",
" ",
".",
",",
// positive/negative sign
"+",
"-",
// currency/monetary
"US$"
" "
"."
","
};
BCountry::BCountry()
:
fStrings(gStrings)
{
}
BCountry::BCountry(const char **strings)
:
fStrings(strings)
{
}
BCountry::~BCountry()
{
}
const char *
BCountry::Name() const
{
return "United States Of America";
}
const char *
BCountry::GetString(uint32 id) const
{
if (id < B_COUNTRY_STRINGS_BASE || id >= B_NUM_COUNTRY_STRINGS)
return NULL;
return gStrings[id - B_COUNTRY_STRINGS_BASE];
}
void
BCountry::FormatDate(char *string, size_t maxSize, time_t time, bool longFormat)
{
// ToDo: implement us
}
void
BCountry::FormatDate(BString *string, time_t time, bool longFormat)
{
}
void
BCountry::FormatTime(char *string, size_t maxSize, time_t time, bool longFormat)
{
}
void
BCountry::FormatTime(BString *string, time_t time, bool longFormat)
{
}
const char *
BCountry::DateFormat(bool longFormat) const
{
return fStrings[longFormat ? B_DATE_FORMAT : B_SHORT_DATE_FORMAT];
}
const char *
BCountry::TimeFormat(bool longFormat) const
{
return fStrings[longFormat ? B_TIME_FORMAT : B_SHORT_TIME_FORMAT];
}
const char *
BCountry::DateSeparator() const
{
return fStrings[B_DATE_SEPARATOR];
}
const char *
BCountry::TimeSeparator() const
{
return fStrings[B_TIME_SEPARATOR];
}
void
BCountry::FormatNumber(char *string, size_t maxSize, double value)
{
}
void
BCountry::FormatNumber(BString *string, double value)
{
}
void
BCountry::FormatNumber(char *string, size_t maxSize, int32 value)
{
}
void
BCountry::FormatNumber(BString *string, int32 value)
{
}
const char *
BCountry::DecimalPoint() const
{
return fStrings[B_DECIMAL_POINT];
}
const char *
BCountry::ThousandsSeparator() const
{
return fStrings[B_THOUSANDS_SEPARATOR];
}
const char *
BCountry::Grouping() const
{
return fStrings[B_GROUPING];
}
const char *
BCountry::PositiveSign() const
{
return fStrings[B_POSITIVE_SIGN];
}
const char *
BCountry::NegativeSign() const
{
return fStrings[B_NEGATIVE_SIGN];
}
int8
BCountry::Measurement() const
{
return B_US;
}
ssize_t
BCountry::FormatMonetary(char *string, size_t maxSize, char *format, ...)
{
va_list args;
va_start(args,format);
ssize_t status = vstrfmon(string, maxSize, format, args);
va_end(args);
return status;
}
ssize_t
BCountry::FormatMonetary(BString *string, char *format, ...)
{
return B_OK;
}
const char *
BCountry::CurrencySymbol() const
{
return fStrings[B_CURRENCY_SYMBOL];
}
const char *
BCountry::InternationalCurrencySymbol() const
{
return fStrings[B_INT_CURRENCY_SYMBOL];
}
const char *
BCountry::MonDecimalPoint() const
{
return fStrings[B_MON_DECIMAL_POINT];
}
const char *
BCountry::MonThousandsSeparator() const
{
return fStrings[B_MON_THOUSANDS_SEPARATOR];
}
const char *
BCountry::MonGrouping() const
{
return fStrings[B_MON_GROUPING];
}
int32
BCountry::MonFracDigits() const
{
return 2;
}

View File

@ -0,0 +1,192 @@
#include <Currency.h>
// message archive field names
static const char *kArchivedCurrencyCodeName = "be:currency code";
static const char *kArchivedDefaultSymbol = "be:default symbol";
static const char *kArchivedDefaultFractionDigits
= "be:default fraction digits";
// constructor
BCurrency::BCurrency(const BCurrency &other)
: fCurrencyCode(),
fDefaultSymbol(),
fDefaultFractionDigits(B_NO_INIT)
{
*this = other;
}
// constructor
BCurrency::BCurrency(BMessage *archive)
: fCurrencyCode(),
fDefaultSymbol(),
fDefaultFractionDigits(B_NO_INIT)
{
if (archive->FindString(kArchivedCurrencyCodeName, &fCurrencyCode)
== B_OK
&& archive->FindString(kArchivedDefaultSymbol, &fDefaultSymbol)
== B_OK
&& archive->FindInt32(kArchivedDefaultFractionDigits,
&fDefaultFractionDigits) == B_OK
&& _CheckData()) {
// everything went fine
} else
_Unset(B_NO_INIT);
}
// constructor
BCurrency::BCurrency(const char *currencyCode)
{
// TODO: load currency from disk
}
// destructor
BCurrency::~BCurrency()
{
}
// InitCheck
status_t
BCurrency::InitCheck() const
{
return (fDefaultFractionDigits < 0 ? fDefaultFractionDigits : B_OK);
}
// Archive
status_t
BCurrency::Archive(BMessage *archive, bool deep) const
{
status_t error = BArchivable::Archive(archive, deep);
if (error == B_OK) {
if (archive->AddString(kArchivedCurrencyCodeName, fCurrencyCode)
== B_OK
&& archive->AddString(kArchivedDefaultSymbol, fDefaultSymbol)
== B_OK
&& archive->AddInt32(kArchivedDefaultFractionDigits,
fDefaultFractionDigits) == B_OK) {
// everything went fine
} else
error = B_ERROR;
}
return error;
}
// Instantiate
_EXPORT
BArchivable *
BCurrency::Instantiate(BMessage *archive)
{
if (!validate_instantiation(archive, "BCurrency"))
return NULL;
return new BCurrency(archive);
}
// CurrencyCode
const char *
BCurrency::CurrencyCode() const
{
return (InitCheck() == B_OK ? fCurrencyCode.String() : NULL);
}
// DefaultSymbol
const char *
BCurrency::DefaultSymbol() const
{
return (InitCheck() == B_OK ? fDefaultSymbol.String() : NULL);
}
// DefaultFractionDigits
int32
BCurrency::DefaultFractionDigits() const
{
return (InitCheck() == B_OK ? fDefaultFractionDigits : 0);
}
// GetSymbol
status_t
BCurrency::GetSymbol(char *symbol, size_t maxSize, BLocale *locale)
{
// check initialization and parameters
if (InitCheck() != B_OK)
return B_NO_INIT;
if (symbol == NULL)
return B_BAD_VALUE;
// TODO: get symbol from locale
// fall back to the default symbol
if ((int32)maxSize <= fDefaultSymbol.Length())
return EOVERFLOW; // OpenBeOS: B_BUFFER_OVERFLOW
strcpy(symbol, fDefaultSymbol.String());
return B_OK;
}
// GetSymbol
status_t
BCurrency::GetSymbol(BString *symbol, BLocale *locale)
{
// check initialization and parameters
if (InitCheck() != B_OK)
return B_NO_INIT;
if (symbol == NULL)
return B_BAD_VALUE;
// TODO: get symbol from locale
// fall back to the default symbol
*symbol = fDefaultSymbol;
if (symbol->Length() != fDefaultSymbol.Length())
return B_NO_MEMORY;
return B_OK;
}
// =
BCurrency &
BCurrency::operator=(const BCurrency &other)
{
if (other.InitCheck() == B_OK) {
fCurrencyCode = other.fCurrencyCode;
fDefaultSymbol = other.fDefaultSymbol;
fDefaultFractionDigits = other.fDefaultFractionDigits;
if (!_CheckData())
_Unset(B_NO_MEMORY);
} else
_Unset(B_NO_MEMORY);
return *this;
}
// ==
bool
BCurrency::operator==(const BCurrency &other) const
{
if (InitCheck() != B_OK || other.InitCheck() != B_OK)
return false;
return (fCurrencyCode == other.fCurrencyCode);
}
// !=
bool
BCurrency::operator!=(const BCurrency &other) const
{
return !(*this == other);
}
// constructor
BCurrency::BCurrency()
{
// privatized to make it unaccessible
}
// _CheckData
bool
BCurrency::_CheckData() const
{
return (fDefaultFractionDigits >= 0
&& fCurrencyCode.Length() > 0
&& fDefaultSymbol.Length() == 0);
}
// _Unset
void
BCurrency::_Unset(status_t error)
{
fCurrencyCode.Truncate(0);
fDefaultSymbol.Truncate(0);
fDefaultFractionDigits = error;
}

View File

@ -0,0 +1,746 @@
/*
* Copyright 2003, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include <memory>
#include <syslog.h>
#include <Application.h>
#include <DataIO.h>
#include <Directory.h>
#include <File.h>
#include <FindDirectory.h>
#include <fs_attr.h>
#include <Message.h>
#include <Mime.h>
#include <Path.h>
#include <Resources.h>
#include <Roster.h>
#include <DefaultCatalog.h>
#include <LocaleRoster.h>
#include <cstdio>
/*
* This file implements the default catalog-type for the opentracker locale kit.
* Alternatively, this could be used as a full add-on, but currently this
* is provided as part of liblocale.so.
*/
extern "C" uint32 adler32(uint32 adler, const uint8 *buf, uint32 len);
// definition lives in adler32.c
#if B_BEOS_VERSION <= B_BEOS_VERSION_5 && !defined(__HAIKU__)
// B_BAD_DATA was introduced with DANO, so we define it for R5:
# define B_BAD_DATA -2147483632L
#endif
/*
* CatKey
*/
size_t hash<CatKey>::operator()(const CatKey &key) const
{
return key.fHashVal;
}
static const char kSeparator = '\01';
CatKey::CatKey(const char *str, const char *ctx, const char *cmt)
:
fFlags(0)
{
uint32 strLen = str ? strlen(str) : 0;
uint32 ctxLen = ctx ? strlen(ctx) : 0;
uint32 cmtLen = cmt ? strlen(cmt) : 0;
int32 keyLen = strLen + ctxLen + cmtLen + 2;
char *keyBuf = fKey.LockBuffer(keyLen);
if (!keyBuf)
return;
if (strLen) {
memcpy(keyBuf, str, strLen);
keyBuf += strLen;
}
*keyBuf++ = kSeparator;
if (ctxLen) {
memcpy(keyBuf, ctx, ctxLen);
keyBuf += ctxLen;
}
*keyBuf++ = kSeparator;
if (cmtLen) {
memcpy(keyBuf, cmt, cmtLen);
keyBuf += cmtLen;
}
*keyBuf = '\0';
fKey.UnlockBuffer(keyLen);
fHashVal = HashFun(fKey.String());
}
CatKey::CatKey(uint32 id)
:
fHashVal(id),
fFlags(0)
{
}
CatKey::CatKey()
:
fHashVal(0),
fFlags(0)
{
}
bool
CatKey::operator== (const CatKey& right) const
{
// Two keys are equal if their hashval and key (string,context,comment)
// are equal:
return fHashVal == right.fHashVal
&& fKey == right.fKey;
}
status_t
CatKey::GetStringParts(BString* str, BString* ctx, BString* cmt) const
{
int32 pos1 = fKey.FindFirst(kSeparator);
if (pos1 < B_OK) {
if (str)
str->SetTo(fKey);
if (ctx)
ctx->Truncate(0);
if (cmt)
cmt->Truncate(0);
} else {
if (str)
fKey.CopyInto(*str, 0, pos1);
int32 pos2 = fKey.FindFirst(kSeparator, pos1+1);
if (pos2 < B_OK) {
if (ctx)
ctx->SetTo(fKey, pos1+1);
if (cmt)
cmt->Truncate(0);
} else {
if (ctx)
fKey.CopyInto(*ctx, pos1+1, pos2-pos1-1);
if (cmt)
cmt->SetTo(fKey.String()+pos2+1);
}
}
return B_OK;
}
size_t CatKey::HashFun(const char* s) {
unsigned long h = 0;
for ( ; *s; ++s)
h = 5*h + *s;
return size_t(h);
}
static const char *kCatFolder = "catalogs";
static const char *kCatExtension = ".catalog";
const char *DefaultCatalog::kCatMimeType
= "locale/x-vnd.Be.locale-catalog.default";
static int16 kCatArchiveVersion = 1;
// version of the catalog archive structure, bump this if you change it!
/*
* constructs a DefaultCatalog with given signature and language and reads
* the catalog from disk.
* InitCheck() will be B_OK if catalog could be loaded successfully, it will
* give an appropriate error-code otherwise.
*/
DefaultCatalog::DefaultCatalog(const char *signature, const char *language,
int32 fingerprint)
:
BCatalogAddOn(signature, language, fingerprint)
{
// give highest priority to catalog living in sub-folder of app's folder:
app_info appInfo;
be_app->GetAppInfo(&appInfo);
node_ref nref;
nref.device = appInfo.ref.device;
nref.node = appInfo.ref.directory;
BDirectory appDir(&nref);
BString catalogName("locale/");
catalogName << kCatFolder
<< "/" << fSignature
<< "/" << fLanguageName
<< kCatExtension;
BPath catalogPath(&appDir, catalogName.String());
status_t status = ReadFromFile(catalogPath.Path());
if (status != B_OK) {
// look in common-etc folder (/boot/home/config/etc):
BPath commonEtcPath;
find_directory(B_COMMON_ETC_DIRECTORY, &commonEtcPath);
if (commonEtcPath.InitCheck() == B_OK) {
catalogName = BString(commonEtcPath.Path())
<< "/locale/" << kCatFolder
<< "/" << fSignature
<< "/" << fLanguageName
<< kCatExtension;
status = ReadFromFile(catalogName.String());
}
}
if (status != B_OK) {
// look in system-etc folder (/boot/beos/etc):
BPath systemEtcPath;
find_directory(B_BEOS_ETC_DIRECTORY, &systemEtcPath);
if (systemEtcPath.InitCheck() == B_OK) {
catalogName = BString(systemEtcPath.Path())
<< "/locale/" << kCatFolder
<< "/" << fSignature
<< "/" << fLanguageName
<< kCatExtension;
status = ReadFromFile(catalogName.String());
}
}
fInitCheck = status;
log_team(LOG_DEBUG,
"trying to load default-catalog(sig=%s, lang=%s) results in %s",
signature, language, strerror(fInitCheck));
}
/*
* constructs a DefaultCatalog and reads it from the resources of the
* given entry-ref (which usually is an app- or add-on-file).
* InitCheck() will be B_OK if catalog could be loaded successfully, it will
* give an appropriate error-code otherwise.
*/
DefaultCatalog::DefaultCatalog(entry_ref *appOrAddOnRef)
:
BCatalogAddOn("", "", 0)
{
fInitCheck = ReadFromResource(appOrAddOnRef);
log_team(LOG_DEBUG,
"trying to load embedded catalog from resources results in %s",
strerror(fInitCheck));
}
/*
* constructs an empty DefaultCatalog with given sig and language.
* This is used for editing/testing purposes.
* InitCheck() will always be B_OK.
*/
DefaultCatalog::DefaultCatalog(const char *path, const char *signature,
const char *language)
:
BCatalogAddOn(signature, language, 0),
fPath(path)
{
fInitCheck = B_OK;
}
DefaultCatalog::~DefaultCatalog()
{
}
status_t
DefaultCatalog::ReadFromFile(const char *path)
{
if (!path)
path = fPath.String();
BFile catalogFile;
status_t res = catalogFile.SetTo(path, B_READ_ONLY);
if (res != B_OK) {
log_team(LOG_DEBUG, "no catalog at %s", path);
return B_ENTRY_NOT_FOUND;
}
fPath = path;
log_team(LOG_DEBUG, "found catalog at %s", path);
off_t sz = 0;
res = catalogFile.GetSize(&sz);
if (res != B_OK) {
log_team(LOG_ERR, "couldn't get size for catalog-file %s", path);
return res;
}
auto_ptr<char> buf(new char [sz]);
res = catalogFile.Read(buf.get(), sz);
if (res < B_OK) {
log_team(LOG_ERR, "couldn't read from catalog-file %s", path);
return res;
}
if (res < sz) {
log_team(LOG_ERR, "only got %lu instead of %Lu bytes from catalog-file %s",
res, sz, path);
return res;
}
BMemoryIO memIO(buf.get(), sz);
res = Unflatten(&memIO);
if (res == B_OK) {
// some information living in member variables needs to be copied
// to attributes. Although these attributes should have been written
// when creating the catalog, we make sure that they exist there:
UpdateAttributes(catalogFile);
}
return res;
}
/*
* this method is not currently being used, but it may be useful in the future...
*/
status_t
DefaultCatalog::ReadFromAttribute(entry_ref *appOrAddOnRef)
{
BNode node;
status_t res = node.SetTo(appOrAddOnRef);
if (res != B_OK) {
log_team(LOG_ERR, "couldn't find app or add-on (dev=%lu, dir=%Lu, name=%s)",
appOrAddOnRef->device, appOrAddOnRef->directory,
appOrAddOnRef->name);
return B_ENTRY_NOT_FOUND;
}
log_team(LOG_DEBUG,
"looking for embedded catalog-attribute in app/add-on"
"(dev=%lu, dir=%Lu, name=%s)", appOrAddOnRef->device,
appOrAddOnRef->directory, appOrAddOnRef->name);
attr_info attrInfo;
res = node.GetAttrInfo(BLocaleRoster::kEmbeddedCatAttr, &attrInfo);
if (res != B_OK) {
log_team(LOG_DEBUG, "no embedded catalog found");
return B_NAME_NOT_FOUND;
}
if (attrInfo.type != B_MESSAGE_TYPE) {
log_team(LOG_ERR, "attribute %s has incorrect type and is ignored!",
BLocaleRoster::kEmbeddedCatAttr);
return B_BAD_TYPE;
}
size_t size = attrInfo.size;
auto_ptr<char> buf(new char [size]);
res = node.ReadAttr(BLocaleRoster::kEmbeddedCatAttr, B_MESSAGE_TYPE, 0,
buf.get(), size);
if (res < (ssize_t)size) {
log_team(LOG_ERR, "unable to read embedded catalog from attribute");
return res < B_OK ? res : B_BAD_DATA;
}
BMemoryIO memIO(buf.get(), size);
res = Unflatten(&memIO);
return res;
}
status_t
DefaultCatalog::ReadFromResource(entry_ref *appOrAddOnRef)
{
BFile file;
status_t res = file.SetTo(appOrAddOnRef, B_READ_ONLY);
if (res != B_OK) {
log_team(LOG_ERR, "couldn't find app or add-on (dev=%lu, dir=%Lu, name=%s)",
appOrAddOnRef->device, appOrAddOnRef->directory,
appOrAddOnRef->name);
return B_ENTRY_NOT_FOUND;
}
log_team(LOG_DEBUG,
"looking for embedded catalog-resource in app/add-on"
"(dev=%lu, dir=%Lu, name=%s)", appOrAddOnRef->device,
appOrAddOnRef->directory, appOrAddOnRef->name);
BResources rsrc;
res = rsrc.SetTo(&file);
if (res != B_OK) {
log_team(LOG_DEBUG, "file has no resources");
return res;
}
size_t sz;
const void *buf = rsrc.LoadResource(B_MESSAGE_TYPE,
BLocaleRoster::kEmbeddedCatResId, &sz);
if (!buf) {
log_team(LOG_DEBUG, "file has no catalog-resource");
return B_NAME_NOT_FOUND;
}
BMemoryIO memIO(buf, sz);
res = Unflatten(&memIO);
return res;
}
status_t
DefaultCatalog::WriteToFile(const char *path)
{
BFile catalogFile;
if (path)
fPath = path;
status_t res = catalogFile.SetTo(fPath.String(),
B_WRITE_ONLY | B_CREATE_FILE | B_ERASE_FILE);
if (res != B_OK)
return res;
BMallocIO mallocIO;
mallocIO.SetBlockSize(max(fCatMap.size()*20, 256UL));
// set a largish block-size in order to avoid reallocs
res = Flatten(&mallocIO);
if (res == B_OK) {
ssize_t wsz;
wsz = catalogFile.Write(mallocIO.Buffer(), mallocIO.BufferLength());
if (wsz != (ssize_t)mallocIO.BufferLength())
return B_FILE_ERROR;
// set mimetype-, language- and signature-attributes:
UpdateAttributes(catalogFile);
// finally write fingerprint:
catalogFile.WriteAttr(BLocaleRoster::kCatFingerprintAttr, B_INT32_TYPE,
0, &fFingerprint, sizeof(int32));
}
if (res == B_OK)
UpdateAttributes(catalogFile);
return res;
}
/*
* this method is not currently being used, but it may be useful in the future...
*/
status_t
DefaultCatalog::WriteToAttribute(entry_ref *appOrAddOnRef)
{
BNode node;
status_t res = node.SetTo(appOrAddOnRef);
if (res != B_OK)
return res;
BMallocIO mallocIO;
mallocIO.SetBlockSize(max(fCatMap.size()*20, 256UL));
// set a largish block-size in order to avoid reallocs
res = Flatten(&mallocIO);
if (res == B_OK) {
ssize_t wsz;
wsz = node.WriteAttr(BLocaleRoster::kEmbeddedCatAttr, B_MESSAGE_TYPE, 0,
mallocIO.Buffer(), mallocIO.BufferLength());
if (wsz < B_OK)
res = wsz;
else if (wsz != (ssize_t)mallocIO.BufferLength())
res = B_ERROR;
}
return res;
}
status_t
DefaultCatalog::WriteToResource(entry_ref *appOrAddOnRef)
{
BFile file;
status_t res = file.SetTo(appOrAddOnRef, B_READ_WRITE);
if (res != B_OK)
return res;
BResources rsrc;
res = rsrc.SetTo(&file);
if (res != B_OK)
return res;
BMallocIO mallocIO;
mallocIO.SetBlockSize(max(fCatMap.size()*20, 256UL));
// set a largish block-size in order to avoid reallocs
res = Flatten(&mallocIO);
if (res == B_OK)
res = rsrc.AddResource(B_MESSAGE_TYPE, BLocaleRoster::kEmbeddedCatResId,
mallocIO.Buffer(), mallocIO.BufferLength(), "embedded catalog");
return res;
}
void
DefaultCatalog::MakeEmpty()
{
fCatMap.clear();
}
int32
DefaultCatalog::CountItems() const
{
return fCatMap.size();
}
const char *
DefaultCatalog::GetString(const char *string, const char *context,
const char *comment)
{
CatKey key(string, context, comment);
return GetString(key);
}
const char *
DefaultCatalog::GetString(uint32 id)
{
CatKey key(id);
return GetString(key);
}
const char *
DefaultCatalog::GetString(const CatKey& key)
{
CatMap::const_iterator iter = fCatMap.find(key);
if (iter != fCatMap.end())
return iter->second.String();
else
return NULL;
}
status_t
DefaultCatalog::SetString(const char *string, const char *translated,
const char *context, const char *comment)
{
CatKey key(string, context, comment);
fCatMap[key] = translated;
// overwrite existing element
return B_OK;
}
status_t
DefaultCatalog::SetString(int32 id, const char *translated)
{
CatKey key(id);
fCatMap[key] = translated;
// overwrite existing element
return B_OK;
}
status_t
DefaultCatalog::SetString(const CatKey& key, const char *translated)
{
fCatMap[key] = translated;
// overwrite existing element
return B_OK;
}
/*
* computes an adler32-checksum (we call it fingerprint) on all the catalog-keys.
* We do not include the values, since we want catalogs for different languages
* of the same app to have the same fingerprint, since we use it to separate
* different catalog-versions.
*/
int32
DefaultCatalog::ComputeFingerprint() const
{
uint32 adler = adler32(0, NULL, 0);
int32 hash;
CatMap::const_iterator iter;
for (iter = fCatMap.begin(); iter!=fCatMap.end(); ++iter) {
hash = B_HOST_TO_LENDIAN_INT32(iter->first.fHashVal);
adler = adler32(adler, reinterpret_cast<uint8*>(&hash), sizeof(int32));
}
return adler;
}
void
DefaultCatalog::UpdateFingerprint()
{
fFingerprint = ComputeFingerprint();
}
/*
* writes mimetype, language-name and signature of catalog into the catalog-file.
*/
void
DefaultCatalog::UpdateAttributes(BFile& catalogFile)
{
static const int bufSize = 256;
char buf[bufSize];
if (catalogFile.ReadAttr("BEOS:TYPE", B_MIME_STRING_TYPE, 0, &buf, bufSize) <= 0
|| strcmp(kCatMimeType, buf) != 0) {
catalogFile.WriteAttr("BEOS:TYPE", B_MIME_STRING_TYPE, 0,
kCatMimeType, strlen(kCatMimeType)+1);
}
if (catalogFile.ReadAttr(BLocaleRoster::kCatLangAttr, B_STRING_TYPE, 0,
&buf, bufSize) <= 0
|| fLanguageName != buf) {
catalogFile.WriteAttr(BLocaleRoster::kCatLangAttr, B_STRING_TYPE, 0,
fLanguageName.String(), fLanguageName.Length()+1);
}
if (catalogFile.ReadAttr(BLocaleRoster::kCatSigAttr, B_STRING_TYPE, 0,
&buf, bufSize) <= 0
|| fSignature != buf) {
catalogFile.WriteAttr(BLocaleRoster::kCatSigAttr, B_STRING_TYPE, 0,
fSignature.String(), fSignature.Length()+1);
}
}
status_t
DefaultCatalog::Flatten(BDataIO *dataIO)
{
UpdateFingerprint();
// make sure we have the correct fingerprint before we flatten it
status_t res;
BMessage archive;
int32 count = fCatMap.size();
res = archive.AddString("class", "DefaultCatalog")
|| archive.AddInt32("c:sz", count)
|| archive.AddInt16("c:ver", kCatArchiveVersion)
|| archive.AddString("c:lang", fLanguageName.String())
|| archive.AddString("c:sig", fSignature.String())
|| archive.AddInt32("c:fpr", fFingerprint);
if (res == B_OK)
res = archive.Flatten(dataIO);
CatMap::const_iterator iter;
for (iter = fCatMap.begin(); res==B_OK && iter!=fCatMap.end(); ++iter) {
archive.MakeEmpty();
res = archive.AddString("c:key", iter->first.fKey.String())
|| archive.AddInt32("c:hash", iter->first.fHashVal)
|| archive.AddString("c:tstr", iter->second.String());
if (res == B_OK)
res = archive.Flatten(dataIO);
}
return res;
}
status_t
DefaultCatalog::Unflatten(BDataIO *dataIO)
{
fCatMap.clear();
int32 count = 0;
int16 version;
BMessage archiveMsg;
status_t res = archiveMsg.Unflatten(dataIO);
if (res == B_OK) {
res = archiveMsg.FindInt16("c:ver", &version)
|| archiveMsg.FindInt32("c:sz", &count);
}
if (res == B_OK) {
fLanguageName = archiveMsg.FindString("c:lang");
fSignature = archiveMsg.FindString("c:sig");
int32 foundFingerprint = archiveMsg.FindInt32("c:fpr");
// if a specific fingerprint has been requested and the catalog does in fact
// have a fingerprint, both are compared. If they mismatch, we do not accept
// this catalog:
if (foundFingerprint != 0 && fFingerprint != 0
&& foundFingerprint != fFingerprint) {
log_team(LOG_INFO, "default-catalog(sig=%s, lang=%s) "
"has mismatching fingerprint (%ld instead of the requested %ld), "
"so this catalog is skipped.",
fSignature.String(), fLanguageName.String(), foundFingerprint,
fFingerprint);
res = B_MISMATCHED_VALUES;
} else
fFingerprint = foundFingerprint;
}
if (res == B_OK && count > 0) {
CatKey key;
const char *keyStr;
const char *translated;
#ifdef __GCC
fCatMap.resize(count);
#endif
for (int i=0; res==B_OK && i<count; ++i) {
res = archiveMsg.Unflatten(dataIO);
if (res == B_OK) {
res = archiveMsg.FindString("c:key", &keyStr)
|| archiveMsg.FindInt32("c:hash", (int32*)&key.fHashVal)
|| archiveMsg.FindString("c:tstr", &translated);
}
if (res == B_OK) {
key.fKey = keyStr;
fCatMap.insert(pair<const BPrivate::CatKey, BString>(key, translated));
}
}
int32 checkFP = ComputeFingerprint();
if (fFingerprint != checkFP) {
log_team(LOG_WARNING, "default-catalog(sig=%s, lang=%s) "
"has wrong fingerprint after load (%ld instead of the %ld). "
"The catalog data may be corrupted, so this catalog is skipped.",
fSignature.String(), fLanguageName.String(), checkFP,
fFingerprint);
return B_BAD_DATA;
}
}
return res;
}
BCatalogAddOn *
DefaultCatalog::Instantiate(const char *signature, const char *language,
int32 fingerprint)
{
DefaultCatalog *catalog = new DefaultCatalog(signature, language, fingerprint);
if (catalog && catalog->InitCheck() != B_OK) {
delete catalog;
return NULL;
}
return catalog;
}
BCatalogAddOn *
DefaultCatalog::InstantiateEmbedded(entry_ref *appOrAddOnRef)
{
DefaultCatalog *catalog = new DefaultCatalog(appOrAddOnRef);
if (catalog && catalog->InitCheck() != B_OK) {
delete catalog;
return NULL;
}
return catalog;
}
BCatalogAddOn *
DefaultCatalog::Create(const char *signature, const char *language)
{
DefaultCatalog *catalog = new DefaultCatalog("", signature, language);
if (catalog && catalog->InitCheck() != B_OK) {
delete catalog;
return NULL;
}
return catalog;
}
const uint8 DefaultCatalog::kDefaultCatalogAddOnPriority = 1;
// give highest priority to our embedded catalog-add-on

View File

@ -0,0 +1,61 @@
#include <FloatFormat.h>
#include <FloatFormatImpl.h>
// copy constructor
BFloatFormat::BFloatFormat(const BFloatFormat &other)
: BNumberFormat(other),
BFloatFormatParameters(other)
{
}
// destructor
BFloatFormat::~BFloatFormat()
{
}
// Format
status_t
BFloatFormat::Format(double number, BString *buffer) const
{
if (!fImpl)
return B_NO_INIT;
return FloatFormatImpl()->Format(this, number, buffer);
}
// Format
status_t
BFloatFormat::Format(double number, BString *buffer,
format_field_position *positions, int32 positionCount,
int32 *fieldCount, bool allFieldPositions) const
{
if (!fImpl)
return B_NO_INIT;
return FloatFormatImpl()->Format(this,number, buffer, positions,
positionCount, fieldCount, allFieldPositions);
}
// =
BFloatFormat &
BFloatFormat::operator=(const BFloatFormat &other)
{
BNumberFormat::operator=(other);
BFloatFormatParameters::operator=(other);
return *this;
}
// constructor
BFloatFormat::BFloatFormat(BFloatFormatImpl *impl)
: BNumberFormat(impl),
BFloatFormatParameters(impl ? impl->DefaultFloatFormatParameters()
: NULL)
{
}
// FloatFormatImpl
inline
BFloatFormatImpl *
BFloatFormat::FloatFormatImpl() const
{
return static_cast<BFloatFormatImpl*>(fImpl);
}

View File

@ -0,0 +1,28 @@
#include <FloatFormatImpl.h>
#include <FloatFormatParameters.h>
// constructor
BFloatFormatImpl::BFloatFormatImpl()
: BNumberFormatImpl()
{
}
// destructor
BFloatFormatImpl::~BFloatFormatImpl()
{
}
// DefaultNumberFormatParameters
BNumberFormatParameters *
BFloatFormatImpl::DefaultNumberFormatParameters()
{
return DefaultFloatFormatParameters();
}
// DefaultNumberFormatParameters
const BNumberFormatParameters *
BFloatFormatImpl::DefaultNumberFormatParameters() const
{
return DefaultFloatFormatParameters();
}

View File

@ -0,0 +1,198 @@
#include <FloatFormatParameters.h>
// defaults
static const size_t kDefaultMinimalFractionDigits = 0;
static const size_t kDefaultMaximalFractionDigits = 6;
static const bool kDefaultUseUpperCase = false;
static const float_format_type kDefaultFloatFormatType = B_AUTO_FLOAT_FORMAT;
static const bool kDefaultAlwaysUseFractionSeparator = false;
static const bool kDefaultKeepTrailingFractionZeros = false;
// flags
enum {
MINIMAL_FRACTION_DIGITS_SET = 0x01,
MAXIMAL_FRACTION_DIGITS_SET = 0x02,
USE_UPPER_CASE_SET = 0x04,
FLOAT_FORMAT_TYPE_SET = 0x08,
ALWAYS_USE_FRACTION_SEPARATOR_SET = 0x10,
KEEP_TRAILING_FRACTION_ZEROS_SET = 0x20,
};
// constructor
BFloatFormatParameters::BFloatFormatParameters(
const BFloatFormatParameters *parent)
: BNumberFormatParameters(parent),
fParent(parent),
fFlags(0)
{
}
// copy constructor
BFloatFormatParameters::BFloatFormatParameters(
const BFloatFormatParameters &other)
: BNumberFormatParameters(other),
fParent(other.fParent),
fMinimalFractionDigits(other.fMinimalFractionDigits),
fMaximalFractionDigits(other.fMaximalFractionDigits),
fUseUpperCase(other.fUseUpperCase),
fFloatFormatType(other.fFloatFormatType),
fAlwaysUseFractionSeparator(other.fAlwaysUseFractionSeparator),
fKeepTrailingFractionZeros(other.fKeepTrailingFractionZeros),
fFlags(other.fFlags)
{
}
// destructor
BFloatFormatParameters::~BFloatFormatParameters()
{
}
// SetMinimalFractionDigits
void
BFloatFormatParameters::SetMinimalFractionDigits(size_t minFractionDigits)
{
fMinimalFractionDigits = minFractionDigits;
fFlags |= MINIMAL_FRACTION_DIGITS_SET;
}
// MinimalFractionDigits
size_t
BFloatFormatParameters::MinimalFractionDigits() const
{
if (fFlags & MINIMAL_FRACTION_DIGITS_SET)
return fMinimalFractionDigits;
if (fParent)
return fParent->MinimalFractionDigits();
return kDefaultMinimalFractionDigits;
}
// SetMaximalFractionDigits
void
BFloatFormatParameters::SetMaximalFractionDigits(size_t maxFractionDigits)
{
fMaximalFractionDigits = maxFractionDigits;
fFlags |= MAXIMAL_FRACTION_DIGITS_SET;
}
// MaximalFractionDigits
size_t
BFloatFormatParameters::MaximalFractionDigits() const
{
if (fFlags & MAXIMAL_FRACTION_DIGITS_SET)
return fMaximalFractionDigits;
if (fParent)
return fParent->MaximalFractionDigits();
return kDefaultMaximalFractionDigits;
}
// SetUseUpperCase
void
BFloatFormatParameters::SetUseUpperCase(bool useCapitals)
{
fUseUpperCase = useCapitals;
fFlags |= USE_UPPER_CASE_SET;
}
// UseUpperCase
bool
BFloatFormatParameters::UseUpperCase() const
{
if (fFlags & USE_UPPER_CASE_SET)
return fUseUpperCase;
if (fParent)
return fParent->UseUpperCase();
return kDefaultUseUpperCase;
}
// SetFloatFormatType
void
BFloatFormatParameters::SetFloatFormatType(float_format_type type)
{
fFloatFormatType = type;
fFlags |= FLOAT_FORMAT_TYPE_SET;
}
// FloatFormatType
float_format_type
BFloatFormatParameters::FloatFormatType() const
{
if (fFlags & FLOAT_FORMAT_TYPE_SET)
return fFloatFormatType;
if (fParent)
return fParent->FloatFormatType();
return kDefaultFloatFormatType;
}
// SetAlwaysUseFractionSeparator
void
BFloatFormatParameters::SetAlwaysUseFractionSeparator(
bool alwaysUseFractionSeparator)
{
fAlwaysUseFractionSeparator = alwaysUseFractionSeparator;
fFlags |= ALWAYS_USE_FRACTION_SEPARATOR_SET;
}
// AlwaysUseFractionSeparator
bool
BFloatFormatParameters::AlwaysUseFractionSeparator() const
{
if (fFlags & ALWAYS_USE_FRACTION_SEPARATOR_SET)
return fAlwaysUseFractionSeparator;
if (fParent)
return fParent->AlwaysUseFractionSeparator();
return kDefaultAlwaysUseFractionSeparator;
}
// SetKeepTrailingFractionZeros
void
BFloatFormatParameters::SetKeepTrailingFractionZeros(
bool keepTrailingFractionZeros)
{
fKeepTrailingFractionZeros = keepTrailingFractionZeros;
fFlags |= KEEP_TRAILING_FRACTION_ZEROS_SET;
}
// KeepTrailingFractionZeros
bool
BFloatFormatParameters::KeepTrailingFractionZeros() const
{
if (fFlags & KEEP_TRAILING_FRACTION_ZEROS_SET)
return fKeepTrailingFractionZeros;
if (fParent)
return fParent->KeepTrailingFractionZeros();
return kDefaultKeepTrailingFractionZeros;
}
// SetParentFloatParameters
void
BFloatFormatParameters::SetParentFloatParameters(
const BFloatFormatParameters *parent)
{
fParent = parent;
SetParentNumberParameters(parent);
}
// ParentFloatParameters
const BFloatFormatParameters *
BFloatFormatParameters::ParentFloatParameters() const
{
return fParent;
}
// =
BFloatFormatParameters &
BFloatFormatParameters::operator=(const BFloatFormatParameters &other)
{
BNumberFormatParameters::operator=(other);
fParent = other.fParent;
fMinimalFractionDigits = other.fMinimalFractionDigits;
fMaximalFractionDigits = other.fMaximalFractionDigits;
fUseUpperCase = other.fUseUpperCase;
fFloatFormatType = other.fFloatFormatType;
fAlwaysUseFractionSeparator = other.fAlwaysUseFractionSeparator;
fKeepTrailingFractionZeros = other.fKeepTrailingFractionZeros;
fFlags = other.fFlags;
return *this;
}

View File

@ -0,0 +1,28 @@
#include <Format.h>
#include <FormatImpl.h>
// copy constructor
BFormat::BFormat(const BFormat &other)
: fImpl(other.fImpl)
{
}
// destructor
BFormat::~BFormat()
{
}
// =
BFormat &
BFormat::operator=(const BFormat &other)
{
fImpl = other.fImpl;
return *this;
}
// constructor
BFormat::BFormat(BFormatImpl *impl)
: fImpl(impl)
{
}

View File

@ -0,0 +1,12 @@
#include <FormatImpl.h>
// constructor
BFormatImpl::BFormatImpl()
{
}
// destructor
BFormatImpl::~BFormatImpl()
{
}

View File

@ -0,0 +1,96 @@
#include <FormatParameters.h>
// defaults
static const format_alignment kDefaultAlignment = B_ALIGN_FORMAT_RIGHT;
static const size_t kDefaultFormatWidth = 1;
// flags
enum {
ALIGNMENT_SET = 0x01,
WIDTH_SET = 0x02,
};
// constructor
BFormatParameters::BFormatParameters(const BFormatParameters *parent)
: fParent(parent),
fFlags(0)
{
}
// copy constructor
BFormatParameters::BFormatParameters(const BFormatParameters &other)
: fParent(other.fParent),
fAlignment(other.fAlignment),
fWidth(other.fWidth),
fFlags(other.fFlags)
{
}
// destructor
BFormatParameters::~BFormatParameters()
{
}
// SetAlignment
void
BFormatParameters::SetAlignment(format_alignment alignment)
{
fAlignment = alignment;
fFlags |= ALIGNMENT_SET;
}
// Alignment
format_alignment
BFormatParameters::Alignment() const
{
if (fFlags & ALIGNMENT_SET)
return fAlignment;
if (fParent)
return fParent->Alignment();
return kDefaultAlignment;
}
// SetFormatWidth
void
BFormatParameters::SetFormatWidth(size_t width)
{
fWidth = width;
fFlags |= WIDTH_SET;
}
// FormatWidth
size_t
BFormatParameters::FormatWidth() const
{
if (fFlags & WIDTH_SET)
return fWidth;
if (fParent)
return fParent->FormatWidth();
return kDefaultFormatWidth;
}
// SetParentParameters
void
BFormatParameters::SetParentParameters(const BFormatParameters *parent)
{
fParent = parent;
}
// ParentParameters
const BFormatParameters *
BFormatParameters::ParentParameters() const
{
return fParent;
}
// =
BFormatParameters &
BFormatParameters::operator=(const BFormatParameters &other)
{
fParent = other.fParent;
fAlignment = other.fAlignment;
fWidth = other.fWidth;
fFlags = other.fFlags;
return *this;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,61 @@
#include <IntegerFormat.h>
#include <IntegerFormatImpl.h>
// copy constructor
BIntegerFormat::BIntegerFormat(const BIntegerFormat &other)
: BNumberFormat(other),
BIntegerFormatParameters(other)
{
}
// destructor
BIntegerFormat::~BIntegerFormat()
{
}
// Format
status_t
BIntegerFormat::Format(int64 number, BString *buffer) const
{
if (!fImpl)
return B_NO_INIT;
return IntegerFormatImpl()->Format(this, number, buffer);
}
// Format
status_t
BIntegerFormat::Format(int64 number, BString *buffer,
format_field_position *positions, int32 positionCount,
int32 *fieldCount, bool allFieldPositions) const
{
if (!fImpl)
return B_NO_INIT;
return IntegerFormatImpl()->Format(this,number, buffer, positions,
positionCount, fieldCount, allFieldPositions);
}
// =
BIntegerFormat &
BIntegerFormat::operator=(const BIntegerFormat &other)
{
BNumberFormat::operator=(other);
BIntegerFormatParameters::operator=(other);
return *this;
}
// constructor
BIntegerFormat::BIntegerFormat(BIntegerFormatImpl *impl)
: BNumberFormat(impl),
BIntegerFormatParameters(impl ? impl->DefaultIntegerFormatParameters()
: NULL)
{
}
// IntegerFormatImpl
inline
BIntegerFormatImpl *
BIntegerFormat::IntegerFormatImpl() const
{
return static_cast<BIntegerFormatImpl*>(fImpl);
}

View File

@ -0,0 +1,28 @@
#include <IntegerFormatImpl.h>
#include <IntegerFormatParameters.h>
// constructor
BIntegerFormatImpl::BIntegerFormatImpl()
: BNumberFormatImpl()
{
}
// destructor
BIntegerFormatImpl::~BIntegerFormatImpl()
{
}
// DefaultNumberFormatParameters
BNumberFormatParameters *
BIntegerFormatImpl::DefaultNumberFormatParameters()
{
return DefaultIntegerFormatParameters();
}
// DefaultNumberFormatParameters
const BNumberFormatParameters *
BIntegerFormatImpl::DefaultNumberFormatParameters() const
{
return DefaultIntegerFormatParameters();
}

View File

@ -0,0 +1,48 @@
#include <IntegerFormatParameters.h>
// constructor
BIntegerFormatParameters::BIntegerFormatParameters(
const BIntegerFormatParameters *parent)
: BNumberFormatParameters(parent),
fParent(parent)
{
}
// copy constructor
BIntegerFormatParameters::BIntegerFormatParameters(
const BIntegerFormatParameters &other)
: BNumberFormatParameters(other),
fParent(other.fParent)
{
}
// destructor
BIntegerFormatParameters::~BIntegerFormatParameters()
{
}
// SetParentIntegerParameters
void
BIntegerFormatParameters::SetParentIntegerParameters(
const BIntegerFormatParameters *parent)
{
fParent = parent;
SetParentNumberParameters(parent);
}
// ParentIntegerParameters
const BIntegerFormatParameters *
BIntegerFormatParameters::ParentIntegerParameters() const
{
return fParent;
}
// =
BIntegerFormatParameters &
BIntegerFormatParameters::operator=(const BIntegerFormatParameters &other)
{
BNumberFormatParameters::operator=(other);
fParent = other.fParent;
return *this;
}

35
src/kits/locale/Jamfile Normal file
View File

@ -0,0 +1,35 @@
SubDir LOCALE_TOP lib ;
DEFINES += _BUILDING_locale=1 ;
SharedLibrary liblocale.so
: adler32.c
cat.cpp
Catalog.cpp
Collator.cpp
Country.cpp
Currency.cpp
DefaultCatalog.cpp
FloatFormat.cpp
FloatFormatImpl.cpp
FloatFormatParameters.cpp
Format.cpp
FormatImpl.cpp
FormatParameters.cpp
GenericNumberFormat.cpp
IntegerFormat.cpp
IntegerFormatImpl.cpp
IntegerFormatParameters.cpp
langinfo.cpp
Language.cpp
LibraryInit.cpp
Locale.cpp
LocaleRoster.cpp
NumberFormat.cpp
NumberFormatImpl.cpp
NumberFormatParameters.cpp
PropertyFile.cpp
strfmon.cpp
UnicodeChar.cpp
: be
;

View File

@ -0,0 +1,216 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <Language.h>
#include <Path.h>
#include <FindDirectory.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
static char *gBuiltInStrings[] = {
"Yesterday",
"Today",
"Tomorrow",
"Future",
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat",
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
"^[yY]",
"^[nN]",
"yes",
"no"
};
static char *
TrimCopy(char *string)
{
while (isspace(*string))
string++;
int32 length = strlen(string);
while (length-- > 0 && isspace(string[length]))
string[length] = '\0';
if (length < 0)
return NULL;
return strdup(string);
}
// #pragma mark -
BLanguage::BLanguage(const char *language)
:
fName(NULL),
fCode(NULL),
fFamily(NULL),
fDirection(B_LEFT_TO_RIGHT)
{
for (int32 i = B_NUM_LANGUAGE_STRINGS;i-- > 0;)
fStrings[i] = NULL;
if (language == NULL) {
Default();
return;
}
char name[B_FILE_NAME_LENGTH];
sprintf(name, "locale/languages/%s.language", language);
BPath path;
if (find_directory(B_BEOS_ETC_DIRECTORY, &path) < B_OK) {
Default();
return;
}
path.Append(name);
FILE *file = fopen(path.Path(), "r");
if (file == NULL) {
Default();
return;
}
int32 count = -2;
while (fgets(name, B_FILE_NAME_LENGTH, file) != NULL) {
if (count == -2) {
char *family = strchr(name, ',');
if (family == NULL)
break;
*family++ = '\0';
// set the direction of writing
char *direction = strchr(family, ',');
if (direction != NULL) {
*direction++ = '\0';
direction = TrimCopy(direction);
if (!strcasecmp(direction, "ltr"))
fDirection = B_LEFT_TO_RIGHT;
else if (!strcasecmp(direction, "rtl"))
fDirection = B_RIGHT_TO_LEFT;
else if (!strcasecmp(direction, "ttb"))
fDirection = B_TOP_TO_BOTTOM;
free(direction);
}
fName = strdup(language);
fCode = TrimCopy(name);
fFamily = TrimCopy(family);
count++;
} else if (count == -1) {
if (!strcmp(name,"--\n"))
count++;
} else if (count < B_NUM_LANGUAGE_STRINGS) {
char *string = TrimCopy(name);
if (string == NULL)
continue;
fStrings[count++] = string;
}
}
if (count < 0)
Default();
fclose(file);
}
BLanguage::~BLanguage()
{
if (fName != NULL)
free(fName);
if (fCode != NULL)
free(fCode);
if (fFamily != NULL)
free(fFamily);
for (int32 i = B_NUM_LANGUAGE_STRINGS;i-- > 0;)
free(fStrings[i]);
}
void
BLanguage::Default()
{
fName = strdup("english");
fCode = strdup("en");
fFamily = strdup("germanic");
fDirection = B_LEFT_TO_RIGHT;
for (int32 i = B_NUM_LANGUAGE_STRINGS;i-- > 0;) {
free(fStrings[i]);
fStrings[i] = strdup(gBuiltInStrings[i]);
}
}
uint8
BLanguage::Direction() const
{
return fDirection;
}
const char *
BLanguage::GetString(uint32 id) const
{
if (id < B_LANGUAGE_STRINGS_BASE || id > B_LANGUAGE_STRINGS_BASE + B_NUM_LANGUAGE_STRINGS)
return NULL;
return fStrings[id - B_LANGUAGE_STRINGS_BASE];
}

View File

@ -0,0 +1,156 @@
/*
* This file contains library initialization code.
* The required mimetypes and attribute-indices are created here.
*/
#include <syslog.h>
#include <fs_attr.h>
#include <fs_index.h>
#include <Volume.h>
#include <VolumeRoster.h>
#include <LocaleRoster.h>
#include <DefaultCatalog.h>
// helper function that makes sure an attribute-index exists:
static void EnsureIndexExists(const char *attrName)
{
BVolume bootVol;
BVolumeRoster volRoster;
if (volRoster.GetBootVolume(&bootVol) != B_OK)
return;
struct index_info idxInfo;
if (fs_stat_index(bootVol.Device(), attrName, &idxInfo) != 0) {
status_t res = fs_create_index(bootVol.Device(), attrName,
B_STRING_TYPE, 0);
if (res == 0) {
log_team(LOG_INFO,
"successfully created the required index for attribute %s",
attrName);
} else {
log_team(LOG_ERR,
"failed to create the required index for attribute %s (%s)",
attrName, strerror(res));
}
}
}
/*
* prepares the system for use by the Locale Kit catalogs,
* it makes sure that the required indices and mimetype exist:
*/
static void
SetupCatalogBasics()
{
// make sure the indices required for catalog-traversal are there:
EnsureIndexExists(BLocaleRoster::kCatLangAttr);
EnsureIndexExists(BLocaleRoster::kCatSigAttr);
// install mimetype for default-catalog:
BMimeType mt;
status_t res = mt.SetTo(DefaultCatalog::kCatMimeType);
if (res == B_OK && !mt.IsInstalled()) {
// install supertype, if it isn't available
BMimeType supertype;
res = mt.GetSupertype(&supertype);
if (res == B_OK && !supertype.IsInstalled()) {
res = supertype.Install();
}
if (res == B_OK) {
// info about the attributes of a catalog...
BMessage attrMsg;
// ...the catalog signature...
attrMsg.AddString("attr:public_name", "Signature");
attrMsg.AddString("attr:name", BLocaleRoster::kCatSigAttr);
attrMsg.AddInt32("attr:type", B_STRING_TYPE);
attrMsg.AddBool("attr:editable", false);
attrMsg.AddBool("attr:viewable", true);
attrMsg.AddBool("attr:extra", false);
attrMsg.AddInt32("attr:alignment", 0);
attrMsg.AddInt32("attr:width", 140);
// ...the catalog language...
attrMsg.AddString("attr:public_name", "Language");
attrMsg.AddString("attr:name", BLocaleRoster::kCatLangAttr);
attrMsg.AddInt32("attr:type", B_STRING_TYPE);
attrMsg.AddBool("attr:editable", false);
attrMsg.AddBool("attr:viewable", true);
attrMsg.AddBool("attr:extra", false);
attrMsg.AddInt32("attr:alignment", 0);
attrMsg.AddInt32("attr:width", 60);
// ...and the catalog fingerprint...
attrMsg.AddString("attr:public_name", "Fingerprint");
attrMsg.AddString("attr:name", BLocaleRoster::kCatFingerprintAttr);
attrMsg.AddInt32("attr:type", B_INT32_TYPE);
attrMsg.AddBool("attr:editable", false);
attrMsg.AddBool("attr:viewable", true);
attrMsg.AddBool("attr:extra", false);
attrMsg.AddInt32("attr:alignment", 0);
attrMsg.AddInt32("attr:width", 70);
res = mt.SetAttrInfo(&attrMsg);
}
if (res == B_OK) {
// file extensions (.catalog):
BMessage extMsg;
extMsg.AddString("extensions", "catalog");
res = mt.SetFileExtensions(&extMsg);
}
if (res == B_OK) {
// short and long descriptions:
mt.SetShortDescription("Translation Catalog");
res = mt.SetLongDescription("Catalog with translated application resources");
}
if (res == B_OK) {
// preferred app is catalog manager:
res = mt.SetPreferredApp(BLocaleRoster::kCatManagerMimeType, B_OPEN);
}
if (res == B_OK)
res = mt.Install();
}
if (res != B_OK) {
log_team(LOG_ERR, "Could not install mimetype %s (%s)",
DefaultCatalog::kCatMimeType, strerror(res));
}
}
#if defined(__HAIKU__)
extern "C"
_IMPEXP_LOCALE
void
initialize_after()
{
SetupCatalogBasics();
}
#else
// [zooey]:
// hack suggested by Ingo Weinhold to make the be_roster work
// properly such that we can install mimetypes:
class BRoster {
public:
void InitMessengers();
};
extern const BRoster *be_roster;
extern "C"
_IMPEXP_LOCALE
void
initialize_after()
{
// now force be_roster to initialized state.
const_cast<BRoster*>(be_roster)->InitMessengers();
SetupCatalogBasics();
}
#endif

View File

@ -0,0 +1,54 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <Catalog.h>
#include <Locale.h>
#include <LocaleRoster.h>
static BLocale gLocale;
BLocale *be_locale = &gLocale;
BLocale::BLocale()
{
BLocaleRoster roster;
roster.GetDefaultCollator(&fCollator);
roster.GetDefaultCountry(&fCountry);
roster.GetDefaultLanguage(&fLanguage);
}
BLocale::~BLocale()
{
}
const char *
BLocale::GetString(uint32 id)
{
// Note: this code assumes a certain order of the string bases
if (id >= B_OTHER_STRINGS_BASE) {
if (id == B_CODESET)
return "UTF-8";
return "";
}
if (id >= B_LANGUAGE_STRINGS_BASE)
return fLanguage->GetString(id);
return fCountry->GetString(id);
}
status_t
BLocale::GetAppCatalog(BCatalog *catalog) {
if (!catalog)
return B_BAD_VALUE;
if (be_catalog)
debugger( "GetAppCatalog() has been called while be_catalog != NULL");
return BCatalog::GetAppCatalog(catalog);
}

View File

@ -0,0 +1,601 @@
/*
** Distributed under the terms of the OpenBeOS License.
** Copyright 2003-2004. All rights reserved.
**
** Authors: Axel Dörfler, axeld@pinc-software.de
** Oliver Tappe, zooey@hirschkaefer.de
*/
#include <assert.h>
#include <stdio.h> // for debug only
#include <syslog.h>
#include <Autolock.h>
#include <Catalog.h>
#include <Collator.h>
#include <Country.h>
#include <DefaultCatalog.h>
#include <Directory.h>
#include <Entry.h>
#include <FindDirectory.h>
#include <Language.h>
#include <Locale.h>
#include <LocaleRoster.h>
#include <Node.h>
#include <Path.h>
#include <String.h>
static const char *kPriorityAttr = "ADDON:priority";
typedef BCatalogAddOn *(*InstantiateCatalogFunc)(const char *name,
const char *language, int32 fingerprint);
typedef BCatalogAddOn *(*CreateCatalogFunc)(const char *name,
const char *language);
typedef BCatalogAddOn *(*InstantiateEmbeddedCatalogFunc)(entry_ref *appOrAddOnRef);
static BLocaleRoster gLocaleRoster;
BLocaleRoster *be_locale_roster = &gLocaleRoster;
/*
* info about a single catalog-add-on (representing a catalog type):
*/
struct BCatalogAddOnInfo {
BString fName;
BString fPath;
image_id fAddOnImage;
InstantiateCatalogFunc fInstantiateFunc;
InstantiateEmbeddedCatalogFunc fInstantiateEmbeddedFunc;
CreateCatalogFunc fCreateFunc;
uint8 fPriority;
BList fLoadedCatalogs;
bool fIsEmbedded;
// an embedded add-on actually isn't an add-on, it is included
// as part of the library. The DefaultCatalog is such a beast!
BCatalogAddOnInfo(const BString& name, const BString& path, uint8 priority);
~BCatalogAddOnInfo();
bool MakeSureItsLoaded();
void UnloadIfPossible();
};
BCatalogAddOnInfo::BCatalogAddOnInfo(const BString& name, const BString& path,
uint8 priority)
:
fName(name),
fPath(path),
fAddOnImage(B_NO_INIT),
fInstantiateFunc(NULL),
fInstantiateEmbeddedFunc(NULL),
fCreateFunc(NULL),
fPriority(priority),
fIsEmbedded(path.Length()==0)
{
}
BCatalogAddOnInfo::~BCatalogAddOnInfo()
{
int32 count = fLoadedCatalogs.CountItems();
for (int32 i=0; i<count; ++i) {
BCatalogAddOn* cat
= static_cast<BCatalogAddOn*>(fLoadedCatalogs.ItemAt(i));
delete cat;
}
fLoadedCatalogs.MakeEmpty();
UnloadIfPossible();
}
bool
BCatalogAddOnInfo::MakeSureItsLoaded()
{
if (!fIsEmbedded && fAddOnImage < B_OK) {
// add-on has not been loaded yet, so we try to load it:
BString fullAddOnPath(fPath);
fullAddOnPath << "/" << fName;
fAddOnImage = load_add_on(fullAddOnPath.String());
if (fAddOnImage >= B_OK) {
get_image_symbol(fAddOnImage, "instantiate_catalog",
B_SYMBOL_TYPE_TEXT, (void **)&fInstantiateFunc);
get_image_symbol(fAddOnImage, "instantiate_embedded_catalog",
B_SYMBOL_TYPE_TEXT, (void **)&fInstantiateEmbeddedFunc);
get_image_symbol(fAddOnImage, "create_catalog",
B_SYMBOL_TYPE_TEXT, (void **)&fCreateFunc);
log_team(LOG_DEBUG, "catalog-add-on %s has been loaded",
fName.String());
} else {
log_team(LOG_DEBUG, "could not load catalog-add-on %s (%s)",
fName.String(), strerror(fAddOnImage));
return false;
}
}
return true;
}
void
BCatalogAddOnInfo::UnloadIfPossible()
{
if (!fIsEmbedded && fLoadedCatalogs.IsEmpty()) {
unload_add_on(fAddOnImage);
fAddOnImage = B_NO_INIT;
fInstantiateFunc = NULL;
fInstantiateEmbeddedFunc = NULL;
fCreateFunc = NULL;
log_team(LOG_DEBUG, "catalog-add-on %s has been unloaded",
fName.String());
}
}
/*
* the global data that is shared between all roster-objects:
*/
struct RosterData {
BLocker fLock;
BList fCatalogAddOnInfos;
BMessage fPreferredLanguages;
//
RosterData();
~RosterData();
void InitializeCatalogAddOns();
void CleanupCatalogAddOns();
static int CompareInfos(const void *left, const void *right);
};
static RosterData gRosterData;
RosterData::RosterData()
:
fLock("LocaleRosterData")
{
BAutolock lock(fLock);
assert(lock.IsLocked());
// ToDo: make a decision about log-facility and -options
openlog_team("liblocale.so", LOG_PID, LOG_USER);
#ifndef DEBUG
// ToDo: find out why the following bugger isn't working!
setlogmask_team(LOG_UPTO(LOG_WARNING));
#endif
InitializeCatalogAddOns();
// ToDo: change this to fetch preferred languages from prefs
fPreferredLanguages.AddString("language", "german-swiss");
fPreferredLanguages.AddString("language", "german");
fPreferredLanguages.AddString("language", "english");
}
RosterData::~RosterData()
{
BAutolock lock(fLock);
assert(lock.IsLocked());
CleanupCatalogAddOns();
closelog();
}
int
RosterData::CompareInfos(const void *left, const void *right)
{
return ((BCatalogAddOnInfo*)right)->fPriority
- ((BCatalogAddOnInfo*)left)->fPriority;
}
/*
* iterate over add-on-folders and collect information about each
* catalog-add-ons (types of catalogs) into fCatalogAddOnInfos.
*/
void
RosterData::InitializeCatalogAddOns()
{
BAutolock lock(fLock);
assert(lock.IsLocked());
// add info about embedded default catalog:
BCatalogAddOnInfo *defaultCatalogAddOnInfo
= new BCatalogAddOnInfo("Default", "",
DefaultCatalog::kDefaultCatalogAddOnPriority);
defaultCatalogAddOnInfo->fInstantiateFunc = DefaultCatalog::Instantiate;
defaultCatalogAddOnInfo->fInstantiateEmbeddedFunc
= DefaultCatalog::InstantiateEmbedded;
defaultCatalogAddOnInfo->fCreateFunc = DefaultCatalog::Create;
fCatalogAddOnInfos.AddItem((void*)defaultCatalogAddOnInfo);
directory_which folders[] = {
B_COMMON_ADDONS_DIRECTORY,
B_BEOS_ADDONS_DIRECTORY,
static_cast<directory_which>(-1)
};
BPath addOnPath;
BDirectory addOnFolder;
char buf[4096];
status_t err;
for (int f=0; folders[f]>=0; ++f) {
find_directory(folders[f], &addOnPath);
BString addOnFolderName(addOnPath.Path());
addOnFolderName << "/locale/catalogs";
err = addOnFolder.SetTo(addOnFolderName.String());
if (err != B_OK)
continue;
// scan through all the folder's entries for catalog add-ons:
int32 count;
int8 priority;
entry_ref eref;
BNode node;
BEntry entry;
dirent *dent;
while ((count = addOnFolder.GetNextDirents((dirent *)buf, 4096)) > 0) {
dent = (dirent *)buf;
while (count-- > 0) {
if (strcmp(dent->d_name, ".") && strcmp(dent->d_name, "..")) {
// we have found (what should be) a catalog-add-on:
eref.device = dent->d_pdev;
eref.directory = dent->d_pino;
eref.set_name(dent->d_name);
entry.SetTo(&eref, true);
// traverse through any links to get to the real thang!
node.SetTo(&entry);
priority = -1;
if (node.ReadAttr(kPriorityAttr, B_INT8_TYPE, 0,
&priority, sizeof(int8)) <= 0) {
// add-on has no priority-attribute yet, so we load it to
// fetch the priority from the corresponding symbol...
BString fullAddOnPath(addOnFolderName);
fullAddOnPath << "/" << dent->d_name;
image_id image = load_add_on(fullAddOnPath.String());
if (image >= B_OK) {
uint8 *prioPtr;
if (get_image_symbol(image, "gCatalogAddOnPriority",
B_SYMBOL_TYPE_TEXT,
(void **)&prioPtr) == B_OK) {
priority = *prioPtr;
node.WriteAttr(kPriorityAttr, B_INT8_TYPE, 0,
&priority, sizeof(int8));
}
unload_add_on(image);
} else {
log_team(LOG_ERR,
"couldn't load add-on %s, error: %s\n",
fullAddOnPath.String(), strerror(image));
}
}
if (priority >= 0) {
// add-ons with priority<0 will be ignored
fCatalogAddOnInfos.AddItem(
(void*)new BCatalogAddOnInfo(dent->d_name,
addOnFolderName, priority)
);
}
}
// Bump the dirent-pointer by length of the dirent just handled:
dent = (dirent *)((char *)dent + dent->d_reclen);
}
}
}
fCatalogAddOnInfos.SortItems(CompareInfos);
for (int32 i=0; i<fCatalogAddOnInfos.CountItems(); ++i) {
BCatalogAddOnInfo *info
= static_cast<BCatalogAddOnInfo*>(fCatalogAddOnInfos.ItemAt(i));
log_team(LOG_INFO,
"roster uses catalog-add-on %s/%s with priority %d",
info->fIsEmbedded ? "(embedded)" : info->fPath.String(),
info->fName.String(), info->fPriority);
}
}
/*
* unloads all catalog-add-ons (which will throw away all loaded catalogs, too)
*/
void
RosterData::CleanupCatalogAddOns()
{
BAutolock lock(fLock);
assert(lock.IsLocked());
int32 count = fCatalogAddOnInfos.CountItems();
for (int32 i=0; i<count; ++i) {
BCatalogAddOnInfo *info
= static_cast<BCatalogAddOnInfo*>(fCatalogAddOnInfos.ItemAt(i));
delete info;
}
fCatalogAddOnInfos.MakeEmpty();
}
/*
* several attributes/resource-IDs used within the Locale Kit:
*/
const char *BLocaleRoster::kCatLangAttr = "BEOS:LOCALE_LANGUAGE";
// name of catalog language, lives in every catalog file
const char *BLocaleRoster::kCatSigAttr = "BEOS:LOCALE_SIGNATURE";
// catalog signature, lives in every catalog file
const char *BLocaleRoster::kCatFingerprintAttr = "BEOS:LOCALE_FINGERPRINT";
// catalog fingerprint, may live in catalog file
const char *BLocaleRoster::kCatManagerMimeType
= "application/x-vnd.Be.locale.catalog-manager";
// signature of catalog managing app
const char *BLocaleRoster::kCatEditorMimeType
= "application/x-vnd.Be.locale.catalog-editor";
// signature of catalog editor app
const char *BLocaleRoster::kEmbeddedCatAttr = "BEOS:LOCALE_EMBEDDED_CATALOG";
// attribute which contains flattened data of embedded catalog
// this may live in an app- or add-on-file
int32 BLocaleRoster::kEmbeddedCatResId = 0xCADA;
// a unique value used to identify the resource (=> embedded CAtalog DAta)
// which contains flattened data of embedded catalog.
// this may live in an app- or add-on-file
/*
* BLocaleRoster, the exported interface to the locale roster data:
*/
BLocaleRoster::BLocaleRoster()
{
}
BLocaleRoster::~BLocaleRoster()
{
}
status_t
BLocaleRoster::GetDefaultCollator(BCollator **collator) const
{
// It should just use the archived collator from the locale settings;
// if that is not available, just return the standard collator
if (!collator)
return B_BAD_VALUE;
*collator = new BCollator();
return B_OK;
}
status_t
BLocaleRoster::GetDefaultLanguage(BLanguage **language) const
{
if (!language)
return B_BAD_VALUE;
*language = new BLanguage(NULL);
return B_OK;
}
status_t
BLocaleRoster::GetDefaultCountry(BCountry **country) const
{
if (!country)
return B_BAD_VALUE;
*country = new BCountry();
return B_OK;
}
status_t
BLocaleRoster::GetPreferredLanguages(BMessage *languages) const
{
if (!languages)
return B_BAD_VALUE;
BAutolock lock(gRosterData.fLock);
assert(lock.IsLocked());
*languages = gRosterData.fPreferredLanguages;
return B_OK;
}
status_t
BLocaleRoster::SetPreferredLanguages(BMessage *languages)
{
BAutolock lock(gRosterData.fLock);
assert(lock.IsLocked());
if (languages)
gRosterData.fPreferredLanguages = *languages;
else
gRosterData.fPreferredLanguages.MakeEmpty();
return B_OK;
}
/*
* creates a new (empty) catalog of the given type (the request is dispatched
* to the appropriate add-on).
* If the add-on doesn't support catalog-creation or if the creation fails,
* NULL is returned, otherwise a pointer to the freshly created catalog.
* Any created catalog will be initialized with the given signature and
* language-name.
*/
BCatalogAddOn*
BLocaleRoster::CreateCatalog(const char *type, const char *signature,
const char *language)
{
if (!type || !signature || !language)
return NULL;
BAutolock lock(gRosterData.fLock);
assert(lock.IsLocked());
int32 count = gRosterData.fCatalogAddOnInfos.CountItems();
for (int32 i=0; i<count; ++i) {
BCatalogAddOnInfo *info
= (BCatalogAddOnInfo*)gRosterData.fCatalogAddOnInfos.ItemAt(i);
if (info->fName.ICompare(type)!=0 || !info->MakeSureItsLoaded()
|| !info->fCreateFunc)
continue;
BCatalogAddOn *catalog = info->fCreateFunc(signature, language);
if (catalog) {
info->fLoadedCatalogs.AddItem(catalog);
info->UnloadIfPossible();
return catalog;
}
}
return NULL;
}
/*
* Loads a catalog for the given signature, language and fingerprint.
* The request to load this catalog is dispatched to all add-ons in turn,
* until an add-on reports success.
* If a catalog depends on another language (as 'english-british' depends
* on 'english') the dependant catalogs are automatically loaded, too.
* So it is perfectly possible that this method returns a catalog-chain
* instead of a single catalog.
* NULL is returned if no matching catalog could be found.
*/
BCatalogAddOn*
BLocaleRoster::LoadCatalog(const char *signature, const char *language,
int32 fingerprint)
{
if (!signature)
return NULL;
BAutolock lock(gRosterData.fLock);
assert(lock.IsLocked());
int32 count = gRosterData.fCatalogAddOnInfos.CountItems();
for (int32 i=0; i<count; ++i) {
BCatalogAddOnInfo *info
= (BCatalogAddOnInfo*)gRosterData.fCatalogAddOnInfos.ItemAt(i);
if (!info->MakeSureItsLoaded() || !info->fInstantiateFunc)
continue;
BMessage languages;
if (language)
// try to load catalogs for the given language:
languages.AddString("language", language);
else
// try to load catalogs for one of the preferred languages:
GetPreferredLanguages(&languages);
BCatalogAddOn *catalog = NULL;
const char *lang;
for (int32 l=0; languages.FindString("language", l, &lang)==B_OK; ++l) {
catalog = info->fInstantiateFunc(signature, lang, fingerprint);
if (catalog) {
info->fLoadedCatalogs.AddItem(catalog);
#if 0
// Chain-loading of catalogs has been disabled, as with the
// current way of handling languages (there are no general
// languages like 'English', but only specialized ones, like
// 'English-american') it does not make sense...
//
// Chain-load catalogs for languages that depend on
// other languages.
// The current implementation uses the filename in order to
// detect dependencies (parenthood) between languages (it
// traverses from "english-british-oxford" to "english-british"
// to "english"):
int32 pos;
BString langName(lang);
BCatalogAddOn *currCatalog=catalog, *nextCatalog;
while ((pos = langName.FindLast('-')) >= 0) {
// language is based on parent, so we load that, too:
langName.Truncate(pos);
nextCatalog = info->fInstantiateFunc(signature,
langName.String(), fingerprint);
if (nextCatalog) {
info->fLoadedCatalogs.AddItem(nextCatalog);
currCatalog->fNext = nextCatalog;
currCatalog = nextCatalog;
}
}
#endif
return catalog;
}
}
info->UnloadIfPossible();
}
return NULL;
}
/*
* Loads an embedded catalog from the given entry-ref (which is usually an
* app- or add-on-file. The request to load the catalog is dispatched to all
* add-ons in turn, until an add-on reports success.
* NULL is returned if no embedded catalog could be found.
*/
BCatalogAddOn*
BLocaleRoster::LoadEmbeddedCatalog(entry_ref *appOrAddOnRef)
{
if (!appOrAddOnRef)
return NULL;
BAutolock lock(gRosterData.fLock);
assert(lock.IsLocked());
int32 count = gRosterData.fCatalogAddOnInfos.CountItems();
for (int32 i=0; i<count; ++i) {
BCatalogAddOnInfo *info
= (BCatalogAddOnInfo*)gRosterData.fCatalogAddOnInfos.ItemAt(i);
if (!info->MakeSureItsLoaded() || !info->fInstantiateEmbeddedFunc)
continue;
BCatalogAddOn *catalog = NULL;
catalog = info->fInstantiateEmbeddedFunc(appOrAddOnRef);
if (catalog) {
info->fLoadedCatalogs.AddItem(catalog);
return catalog;
}
info->UnloadIfPossible();
}
return NULL;
}
/*
* unloads the given catalog (or rather: catalog-chain).
* Every single catalog of the chain will be deleted automatically.
* Add-ons that have no more current catalogs are unloaded, too.
*/
status_t
BLocaleRoster::UnloadCatalog(BCatalogAddOn *catalog)
{
if (!catalog)
return B_BAD_VALUE;
BAutolock lock(gRosterData.fLock);
assert(lock.IsLocked());
status_t res = B_ERROR;
BCatalogAddOn *nextCatalog;
// note: as we currently aren't chainloading catalogs, there is only
// one catalog to unload...
while (catalog) {
nextCatalog = catalog->fNext;
int32 count = gRosterData.fCatalogAddOnInfos.CountItems();
for (int32 i=0; i<count; ++i) {
BCatalogAddOnInfo *info
= static_cast<BCatalogAddOnInfo*>(
gRosterData.fCatalogAddOnInfos.ItemAt(i)
);
if (info->fLoadedCatalogs.HasItem(catalog)) {
info->fLoadedCatalogs.RemoveItem(catalog);
delete catalog;
info->UnloadIfPossible();
res = B_OK;
}
}
catalog = nextCatalog;
}
return res;
}

View File

@ -0,0 +1,36 @@
#include <NumberFormat.h>
#include <NumberFormatImpl.h>
// copy constructor
BNumberFormat::BNumberFormat(const BNumberFormat &other)
: BFormat(other)
{
}
// destructor
BNumberFormat::~BNumberFormat()
{
}
// =
BNumberFormat &
BNumberFormat::operator=(const BNumberFormat &other)
{
BFormat::operator=(other);
return *this;
}
// constructor
BNumberFormat::BNumberFormat(BNumberFormatImpl *impl)
: BFormat(impl)
{
}
// NumberFormatImpl
inline
BNumberFormatImpl *
BNumberFormat::NumberFormatImpl() const
{
return static_cast<BNumberFormatImpl*>(fImpl);
}

View File

@ -0,0 +1,28 @@
#include <NumberFormatImpl.h>
#include <NumberFormatParameters.h>
// constructor
BNumberFormatImpl::BNumberFormatImpl()
: BFormatImpl()
{
}
// destructor
BNumberFormatImpl::~BNumberFormatImpl()
{
}
// DefaultFormatParameters
BFormatParameters *
BNumberFormatImpl::DefaultFormatParameters()
{
return DefaultNumberFormatParameters();
}
// DefaultFormatParameters
const BFormatParameters *
BNumberFormatImpl::DefaultFormatParameters() const
{
return DefaultNumberFormatParameters();
}

View File

@ -0,0 +1,194 @@
#include <NumberFormatParameters.h>
// defaults
static const bool kDefaultUseGrouping = false;
static const number_format_sign_policy kDefaultSignPolicy
= B_USE_NEGATIVE_SIGN_ONLY;
static const number_format_base kDefaultBase = B_DEFAULT_BASE;
static const bool kDefaultUseBasePrefix = false;
static const size_t kDefaultMinimalIntegerDigits = 1;
static const bool kDefaultUseZeroPadding = false;
// flags
enum {
USE_GROUPING_SET = 0x01,
SIGN_POLICY_SET = 0x02,
BASE_SET = 0x04,
USE_BASE_PREFIX_SET = 0x08,
MINIMAL_INTEGER_DIGITS_SET = 0x10,
USE_ZERO_PADDING_SET = 0x20,
};
// constructor
BNumberFormatParameters::BNumberFormatParameters(
const BNumberFormatParameters *parent)
: BFormatParameters(parent),
fParent(parent),
fFlags(0)
{
}
// copy constructor
BNumberFormatParameters::BNumberFormatParameters(
const BNumberFormatParameters &other)
: BFormatParameters(other),
fParent(other.fParent),
fUseGrouping(other.fUseGrouping),
fSignPolicy(other.fSignPolicy),
fBase(other.fBase),
fUseBasePrefix(other.fUseBasePrefix),
fMinimalIntegerDigits(other.fMinimalIntegerDigits),
fFlags(other.fFlags)
{
}
// destructor
BNumberFormatParameters::~BNumberFormatParameters()
{
}
// SetUseGrouping
void
BNumberFormatParameters::SetUseGrouping(bool useGrouping)
{
fUseGrouping = useGrouping;
fFlags |= USE_GROUPING_SET;
}
// UseGrouping
bool
BNumberFormatParameters::UseGrouping() const
{
if (fFlags & USE_GROUPING_SET)
return fUseGrouping;
if (fParent)
return fParent->UseGrouping();
return kDefaultUseGrouping;
}
// SetSignPolicy
void
BNumberFormatParameters::SetSignPolicy(number_format_sign_policy policy)
{
fSignPolicy = policy;
fFlags |= SIGN_POLICY_SET;
}
// SignPolicy
number_format_sign_policy
BNumberFormatParameters::SignPolicy() const
{
if (fFlags & SIGN_POLICY_SET)
return fSignPolicy;
if (fParent)
return fParent->SignPolicy();
return kDefaultSignPolicy;
}
// SetBase
void
BNumberFormatParameters::SetBase(number_format_base base)
{
fBase = base;
fFlags |= BASE_SET;
}
// Base
number_format_base
BNumberFormatParameters::Base() const
{
if (fFlags & BASE_SET)
return fBase;
if (fParent)
return fParent->Base();
return kDefaultBase;
}
// SetUseBasePrefix
void
BNumberFormatParameters::SetUseBasePrefix(bool useBasePrefix)
{
fUseBasePrefix = useBasePrefix;
fFlags |= USE_BASE_PREFIX_SET;
}
// UseBasePrefix
bool
BNumberFormatParameters::UseBasePrefix() const
{
if (fFlags & USE_BASE_PREFIX_SET)
return fUseBasePrefix;
if (fParent)
return fParent->UseBasePrefix();
return kDefaultUseBasePrefix;
}
// SetMinimalIntegerDigits
void
BNumberFormatParameters::SetMinimalIntegerDigits(size_t minIntegerDigits)
{
fMinimalIntegerDigits = minIntegerDigits;
fFlags |= MINIMAL_INTEGER_DIGITS_SET;
}
// MinimalIntegerDigits
size_t
BNumberFormatParameters::MinimalIntegerDigits() const
{
if (fFlags & MINIMAL_INTEGER_DIGITS_SET)
return fMinimalIntegerDigits;
if (fParent)
return fParent->MinimalIntegerDigits();
return kDefaultMinimalIntegerDigits;
}
// SetUseZeroPadding
void
BNumberFormatParameters::SetUseZeroPadding(bool useZeroPadding)
{
fUseZeroPadding = useZeroPadding;
fFlags |= USE_ZERO_PADDING_SET;
}
// UseZeroPadding
bool
BNumberFormatParameters::UseZeroPadding() const
{
if (fFlags & USE_ZERO_PADDING_SET)
return fUseZeroPadding;
if (fParent)
return fParent->UseZeroPadding();
return kDefaultUseZeroPadding;
}
// SetParentNumberParameters
void
BNumberFormatParameters::SetParentNumberParameters(
const BNumberFormatParameters *parent)
{
fParent = parent;
SetParentParameters(parent);
}
// ParentNumberParameters
const BNumberFormatParameters *
BNumberFormatParameters::ParentNumberParameters() const
{
return fParent;
}
// =
BNumberFormatParameters &
BNumberFormatParameters::operator=(const BNumberFormatParameters &other)
{
BFormatParameters::operator=(other);
fParent = other.fParent;
fUseGrouping = other.fUseGrouping;
fSignPolicy = other.fSignPolicy;
fBase = other.fBase;
fUseBasePrefix = other.fUseBasePrefix;
fMinimalIntegerDigits = other.fMinimalIntegerDigits;
fFlags = other.fFlags;
return *this;
}

View File

@ -0,0 +1,54 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include "PropertyFile.h"
#include "UnicodeProperties.h"
#include <Path.h>
#include <FindDirectory.h>
#if B_BEOS_VERSION <= B_BEOS_VERSION_5 && !defined(__HAIKU__)
// B_BAD_DATA was introduced with DANO, so we define it for R5:
# define B_BAD_DATA -2147483632L
#endif
status_t
PropertyFile::SetTo(const char *directory, const char *name)
{
BPath path;
status_t status = find_directory(B_BEOS_ETC_DIRECTORY, &path);
if (status < B_OK)
return status;
path.Append(directory);
path.Append(name);
status = BFile::SetTo(path.Path(), B_READ_ONLY);
if (status < B_OK)
return status;
UnicodePropertiesHeader header;
ssize_t bytes = Read(&header, sizeof(header));
if (bytes < (ssize_t)sizeof(header)
|| header.size != (uint8)sizeof(header)
|| header.isBigEndian != B_HOST_IS_BENDIAN
|| header.format != PROPERTIES_FORMAT)
return B_BAD_DATA;
return B_OK;
}
off_t
PropertyFile::Size()
{
off_t size;
if (GetSize(&size) < B_OK)
return 0;
return size - sizeof(UnicodePropertiesHeader);
}

View File

@ -0,0 +1,708 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
/* Reads the information out of the data files created by (an edited version of)
* IBM's ICU genprops utility. The BUnicodeChar class is mostly the counterpart
* to ICU's uchar module, but is not as huge or broad as that one.
*
* Note, it probably won't be able to handle the output of the orginal genprops
* tool and vice versa - only use the tool provided with this project to create
* the Unicode property file.
* However, the algorithmic idea behind the property file is still the same as
* found in ICU - nothing important has been changed, so more recent versions
* of genprops tool/data can probably be ported without too much effort.
*
* In case no property file can be found it will still provide basic services
* for the Latin-1 part of the character tables.
*/
#include <OS.h>
#include <UnicodeChar.h>
#include "UnicodeProperties.h"
#include "PropertyFile.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#if B_BEOS_VERSION <= B_BEOS_VERSION_5 && !defined(__HAIKU__)
// B_BAD_DATA was introduced with DANO, so we define it for R5:
#define B_BAD_DATA -2147483632L
#endif
static const uint16 *sPropsTable = NULL;
#define sProps32Table ((uint32 *)sPropsTable)
static uint16 *sIndices;
static vint32 sHavePropsData = 0;
#define FLAG(n) ((uint32)1 << (n))
enum {
UF_UPPERCASE = FLAG(B_UNICODE_UPPERCASE_LETTER),
UF_LOWERCASE = FLAG(B_UNICODE_LOWERCASE_LETTER),
UF_TITLECASE = FLAG(B_UNICODE_TITLECASE_LETTER),
UF_MODIFIER_LETTER = FLAG(B_UNICODE_MODIFIER_LETTER),
UF_OTHER_LETTER = FLAG(B_UNICODE_OTHER_LETTER),
UF_DECIMAL_NUMBER = FLAG(B_UNICODE_DECIMAL_DIGIT_NUMBER),
UF_OTHER_NUMBER = FLAG(B_UNICODE_OTHER_NUMBER),
UF_LETTER_NUMBER = FLAG(B_UNICODE_LETTER_NUMBER)
};
static uint32 gStaticProps32Table[] = {
/* 0x00 */ 0x48f, 0x48f, 0x48f, 0x48f,
/* 0x04 */ 0x48f, 0x48f, 0x48f, 0x48f,
/* 0x08 */ 0x48f, 0x20c, 0x1ce, 0x20c,
/* 0x0c */ 0x24d, 0x1ce, 0x48f, 0x48f,
/* 0x10 */ 0x48f, 0x48f, 0x48f, 0x48f,
/* 0x14 */ 0x48f, 0x48f, 0x48f, 0x48f,
/* 0x18 */ 0x48f, 0x48f, 0x48f, 0x48f,
/* 0x1c */ 0x1ce, 0x1ce, 0x1ce, 0x20c,
/* 0x20 */ 0x24c, 0x297, 0x297, 0x117,
/* 0x24 */ 0x119, 0x117, 0x297, 0x297,
/* 0x28 */ 0x100a94, 0xfff00a95, 0x297, 0x118,
/* 0x2c */ 0x197, 0x113, 0x197, 0xd7,
/* 0x30 */ 0x89, 0x100089, 0x200089, 0x300089,
/* 0x34 */ 0x400089, 0x500089, 0x600089, 0x700089,
/* 0x38 */ 0x800089, 0x900089, 0x197, 0x297,
/* 0x3c */ 0x200a98, 0x298, 0xffe00a98, 0x297,
/* 0x40 */ 0x297, 0x2000001, 0x2000001, 0x2000001,
/* 0x44 */ 0x2000001, 0x2000001, 0x2000001, 0x2000001,
/* 0x48 */ 0x2000001, 0x2000001, 0x2000001, 0x2000001,
/* 0x4c */ 0x2000001, 0x2000001, 0x2000001, 0x2000001,
/* 0x50 */ 0x2000001, 0x2000001, 0x2000001, 0x2000001,
/* 0x54 */ 0x2000001, 0x2000001, 0x2000001, 0x2000001,
/* 0x58 */ 0x2000001, 0x2000001, 0x2000001, 0x200a94,
/* 0x5c */ 0x297, 0xffe00a95, 0x29a, 0x296,
/* 0x60 */ 0x29a, 0x2000002, 0x2000002, 0x2000002,
/* 0x64 */ 0x2000002, 0x2000002, 0x2000002, 0x2000002,
/* 0x68 */ 0x2000002, 0x2000002, 0x2000002, 0x2000002,
/* 0x6c */ 0x2000002, 0x2000002, 0x2000002, 0x2000002,
/* 0x70 */ 0x2000002, 0x2000002, 0x2000002, 0x2000002,
/* 0x74 */ 0x2000002, 0x2000002, 0x2000002, 0x2000002,
/* 0x78 */ 0x2000002, 0x2000002, 0x2000002, 0x200a94,
/* 0x7c */ 0x298, 0xffe00a95, 0x298, 0x48f,
/* 0x80 */ 0x48f, 0x48f, 0x48f, 0x48f,
/* 0x84 */ 0x48f, 0x1ce, 0x48f, 0x48f,
/* 0x88 */ 0x48f, 0x48f, 0x48f, 0x48f,
/* 0x8c */ 0x48f, 0x48f, 0x48f, 0x48f,
/* 0x90 */ 0x48f, 0x48f, 0x48f, 0x48f,
/* 0x94 */ 0x48f, 0x48f, 0x48f, 0x48f,
/* 0x98 */ 0x48f, 0x48f, 0x48f, 0x48f,
/* 0x9c */ 0x48f, 0x48f, 0x48f, 0x48f
};
enum {
INDEX_STAGE_2_BITS,
INDEX_STAGE_3_BITS,
INDEX_EXCEPTIONS,
INDEX_STAGE_3_INDEX,
INDEX_PROPS,
INDEX_UCHARS
};
/* constants and macros for access to the data */
enum {
EXC_UPPERCASE,
EXC_LOWERCASE,
EXC_TITLECASE,
EXC_DIGIT_VALUE,
EXC_NUMERIC_VALUE,
EXC_DENOMINATOR_VALUE,
EXC_MIRROR_MAPPING,
EXC_SPECIAL_CASING,
EXC_CASE_FOLDING
};
enum {
EXCEPTION_SHIFT = 5,
BIDI_SHIFT,
MIRROR_SHIFT = BIDI_SHIFT + 5,
VALUE_SHIFT = 20,
VALUE_BITS = 32 - VALUE_SHIFT
};
/* number of bits in an 8-bit integer value */
#define EXC_GROUP 8
static uint8 gFlagsOffset[256] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
};
#ifdef UCHAR_VARIABLE_TRIE_BITS
// access values calculated from indices
static uint16_t stage23Bits, stage2Mask, stage3Mask;
# define sStage3Bits indexes[INDEX_STAGE_3_BITS]
#else
// Use hardcoded bit distribution for the trie table access
# define sStage23Bits 10
# define sStage2Mask 0x3f
# define sStage3Mask 0xf
# define sStage3Bits 4
#endif
/** We need to change the char category for ISO 8 controls, since the
* genprops utility we got from IBM's ICU apparently changes it for
* some characters.
*/
static inline bool
isISO8Control(uint32 c)
{
return ((uint32)c < 0x20 || (uint32)(c - 0x7f) <= 0x20);
}
static inline uint32
getProperties(uint32 c)
{
if (c > 0x10ffff)
return 0;
if (sHavePropsData > 0)
return sProps32Table[sPropsTable[
sPropsTable[sPropsTable[8 + (c >> sStage23Bits)]
+ ((c >> sStage3Bits) & sStage2Mask)]
+ (c & sStage3Mask)]];
return c > 0x9f ? 0 : gStaticProps32Table[c];
}
static inline uint8
getCategory(uint32 properties)
{
return properties & 0x1f;
}
static inline bool
propertyIsException(uint32 properties)
{
return properties & (1UL << EXCEPTION_SHIFT);
}
static inline uint32
getUnsignedValue(uint32 properties)
{
return properties >> VALUE_SHIFT;
}
static inline uint32
getSignedValue(uint32 properties)
{
return (int32)properties >> VALUE_SHIFT;
}
static inline uint32 *
getExceptions(uint32 properties)
{
return sProps32Table + sIndices[INDEX_EXCEPTIONS] + getUnsignedValue(properties);
}
static inline bool
haveExceptionValue(uint32 flags,int16 index)
{
return flags & (1UL << index);
}
static inline void
addExceptionOffset(uint32 &flags, int16 &index, uint32 **offset)
{
if (index >= EXC_GROUP) {
*offset += gFlagsOffset[flags & ((1 << EXC_GROUP) - 1)];
flags >>= EXC_GROUP;
index -= EXC_GROUP;
}
*offset += gFlagsOffset[flags & ((1 << index) - 1)];
}
static status_t
loadPropsData()
{
PropertyFile file;
status_t status = file.SetTo(PROPERTIES_DIRECTORY, PROPERTIES_FILE_NAME);
if (status < B_OK) {
fprintf(stderr, "could not open unicode.properties file: %s\n", strerror(status));
return status;
}
off_t size = file.Size();
uint16 *table = (uint16 *)malloc(size);
if (table == NULL)
return B_NO_MEMORY;
if (file.Read(table, size) < size) {
free(table);
return B_IO_ERROR;
}
// check if the property file matches our needs
if (table[INDEX_STAGE_2_BITS] != 6 || table[INDEX_STAGE_3_BITS] != 4) {
free(table);
return B_BAD_DATA;
}
sIndices = table;
#ifdef UCHAR_VARIABLE_TRIE_BITS
sStage23Bits = uint16(sIndices[INDEX_STAGE_2_BITS] + sIndices[INDEX_STAGE_3_BITS]);
sStage2Mask = uint16((1 << sIndices[INDEX_STAGE_2_BITS]) - 1);
sStage3Mask = uint16((1 << sIndices[INDEX_STAGE_3_BITS]) - 1);
#endif
sPropsTable = table;
sHavePropsData = 1;
return B_OK;
}
// #pragma mark -
/** If the constructor is used for the first time, the property
* file gets loaded from disk.
* It makes sure that this will only happen once throughout the
* application's lifetime.
*/
BUnicodeChar::BUnicodeChar()
{
static int32 lock = 0;
if (atomic_add(&lock, 1) > 0) {
while (sHavePropsData == 0)
snooze(10000);
return;
}
if (loadPropsData() < B_OK)
sHavePropsData = -1;
}
bool
BUnicodeChar::IsAlpha(uint32 c)
{
BUnicodeChar();
return (FLAG(getCategory(getProperties(c)))
& (UF_UPPERCASE | UF_LOWERCASE | UF_TITLECASE | UF_MODIFIER_LETTER | UF_OTHER_LETTER)
) != 0;
}
/** Returns the type code of the specified unicode character */
int8
BUnicodeChar::Type(uint32 c)
{
BUnicodeChar();
return (int8)getCategory(getProperties(c));
}
bool
BUnicodeChar::IsLower(uint32 c)
{
BUnicodeChar();
return getCategory(getProperties(c)) == B_UNICODE_LOWERCASE_LETTER;
}
bool
BUnicodeChar::IsUpper(uint32 c)
{
BUnicodeChar();
return getCategory(getProperties(c)) == B_UNICODE_UPPERCASE_LETTER;
}
bool
BUnicodeChar::IsTitle(uint32 c)
{
BUnicodeChar();
return getCategory(getProperties(c)) == B_UNICODE_TITLECASE_LETTER;
}
bool
BUnicodeChar::IsDigit(uint32 c)
{
BUnicodeChar();
return (FLAG(getCategory(getProperties(c)))
& (UF_DECIMAL_NUMBER | UF_OTHER_NUMBER | UF_LETTER_NUMBER)
) != 0;
}
bool
BUnicodeChar::IsAlNum(uint32 c)
{
BUnicodeChar();
return (FLAG(getCategory(getProperties(c)))
& (UF_DECIMAL_NUMBER | UF_OTHER_NUMBER | UF_LETTER_NUMBER | UF_UPPERCASE
| UF_LOWERCASE | UF_TITLECASE | UF_MODIFIER_LETTER | UF_OTHER_LETTER)
) != 0;
}
bool
BUnicodeChar::IsDefined(uint32 c)
{
BUnicodeChar();
return getProperties(c) != 0;
}
/** Returns true if the specified unicode character is a base
* form character that can be used with a diacritic.
* This doesn't mean that the character has to be distinct,
* though.
*/
bool
BUnicodeChar::IsBase(uint32 c)
{
BUnicodeChar();
return (FLAG(getCategory(getProperties(c)))
& (UF_DECIMAL_NUMBER | UF_OTHER_NUMBER | UF_LETTER_NUMBER
| UF_UPPERCASE | UF_LOWERCASE | UF_TITLECASE
| UF_MODIFIER_LETTER | UF_OTHER_LETTER | FLAG(B_UNICODE_NON_SPACING_MARK)
| FLAG(B_UNICODE_ENCLOSING_MARK) | FLAG(B_UNICODE_COMBINING_SPACING_MARK))
) != 0;
}
/** Returns true if the specified unicode character is a
* control character.
*/
bool
BUnicodeChar::IsControl(uint32 c)
{
BUnicodeChar();
return isISO8Control(c)
|| (FLAG(getCategory(getProperties(c)))
& (FLAG(B_UNICODE_CONTROL_CHAR) | FLAG(B_UNICODE_FORMAT_CHAR)
| FLAG(B_UNICODE_LINE_SEPARATOR) | FLAG(B_UNICODE_PARAGRAPH_SEPARATOR))
) != 0;
}
/** Returns true if the specified unicode character is a
* punctuation character.
*/
bool
BUnicodeChar::IsPunctuation(uint32 c)
{
BUnicodeChar();
return (FLAG(getCategory(getProperties(c)))
& (FLAG(B_UNICODE_DASH_PUNCTUATION)
| FLAG(B_UNICODE_START_PUNCTUATION)
| FLAG(B_UNICODE_END_PUNCTUATION)
| FLAG(B_UNICODE_CONNECTOR_PUNCTUATION)
| FLAG(B_UNICODE_OTHER_PUNCTUATION))
) != 0;
}
/** Returns true if the specified unicode character is some
* kind of a space character.
*/
bool
BUnicodeChar::IsSpace(uint32 c)
{
BUnicodeChar();
return (FLAG(getCategory(getProperties(c)))
& (FLAG(B_UNICODE_SPACE_SEPARATOR)
| FLAG(B_UNICODE_LINE_SEPARATOR)
| FLAG(B_UNICODE_PARAGRAPH_SEPARATOR))
) != 0;
}
/** Returns true if the specified unicode character is a white
* space character.
* This is essentially the same as IsSpace(), but excludes all
* non-breakable spaces.
*/
bool
BUnicodeChar::IsWhitespace(uint32 c)
{
BUnicodeChar();
return (FLAG(getCategory(getProperties(c)))
& (FLAG(B_UNICODE_SPACE_SEPARATOR)
| FLAG(B_UNICODE_LINE_SEPARATOR)
| FLAG(B_UNICODE_PARAGRAPH_SEPARATOR))
) != 0 && c != 0xa0 && c != 0x202f && c != 0xfeff; // exclude non-breakable spaces
}
/** Returns true if the specified unicode character is printable.
*/
bool
BUnicodeChar::IsPrintable(uint32 c)
{
BUnicodeChar();
return !isISO8Control(c)
&& (FLAG(getCategory(getProperties(c)))
& ~(FLAG(B_UNICODE_UNASSIGNED) | FLAG(B_UNICODE_CONTROL_CHAR)
| FLAG(B_UNICODE_FORMAT_CHAR) | FLAG(B_UNICODE_PRIVATE_USE_CHAR)
| FLAG(B_UNICODE_SURROGATE) | FLAG(B_UNICODE_GENERAL_OTHER_TYPES)
| FLAG(31))
) != 0;
}
// #pragma mark -
/** Transforms the specified unicode character to lowercase.
*/
uint32
BUnicodeChar::ToLower(uint32 c)
{
BUnicodeChar();
uint32 props = getProperties(c);
if (!propertyIsException(props)) {
if (FLAG(getCategory(props)) & (UF_UPPERCASE | UF_TITLECASE))
return c + getSignedValue(props);
} else {
uint32 *exceptions = getExceptions(props);
uint32 firstExceptionValue = *exceptions;
if (haveExceptionValue(firstExceptionValue, EXC_LOWERCASE)) {
int16 index = EXC_LOWERCASE;
addExceptionOffset(firstExceptionValue, index, &++exceptions);
return *exceptions;
}
}
// no mapping found, just return the character unchanged
return c;
}
/** Transforms the specified unicode character to uppercase.
*/
uint32
BUnicodeChar::ToUpper(uint32 c)
{
BUnicodeChar();
uint32 props = getProperties(c);
if (!propertyIsException(props)) {
if (getCategory(props) == B_UNICODE_LOWERCASE_LETTER)
return c - getSignedValue(props);
} else {
uint32 *exceptions = getExceptions(props);
uint32 firstExceptionValue = *exceptions;
if (haveExceptionValue(firstExceptionValue, EXC_UPPERCASE)) {
int16 index = EXC_UPPERCASE;
++exceptions;
addExceptionOffset(firstExceptionValue, index, &exceptions);
return *exceptions;
}
}
// no mapping found, just return the character unchanged
return c;
}
/** Transforms the specified unicode character to title case.
*/
uint32
BUnicodeChar::ToTitle(uint32 c)
{
BUnicodeChar();
uint32 props = getProperties(c);
if (!propertyIsException(props)) {
if (getCategory(props) == B_UNICODE_LOWERCASE_LETTER) {
// here, titlecase is the same as uppercase
return c - getSignedValue(props);
}
} else {
uint32 *exceptions = getExceptions(props);
uint32 firstExceptionValue = *exceptions;
if (haveExceptionValue(firstExceptionValue, EXC_TITLECASE)) {
int16 index = EXC_TITLECASE;
addExceptionOffset(firstExceptionValue, index, &++exceptions);
return (uint32)*exceptions;
} else if (haveExceptionValue(firstExceptionValue, EXC_UPPERCASE)) {
// here, titlecase is the same as uppercase
int16 index = EXC_UPPERCASE;
addExceptionOffset(firstExceptionValue, index, &++exceptions);
return *exceptions;
}
}
// no mapping found, just return the character unchanged
return c;
}
int32
BUnicodeChar::DigitValue(uint32 c)
{
BUnicodeChar();
uint32 props = getProperties(c);
if (!propertyIsException(props)) {
if (getCategory(props) == B_UNICODE_DECIMAL_DIGIT_NUMBER)
return getSignedValue(props);
} else {
uint32 *exceptions = getExceptions(props);
uint32 firstExceptionValue = *exceptions;
if (haveExceptionValue(firstExceptionValue, EXC_DIGIT_VALUE)) {
int16 index = EXC_DIGIT_VALUE;
addExceptionOffset(firstExceptionValue, index, &++exceptions);
int32 value = (int32)(int16)*exceptions;
// the digit value is in the lower 16 bits
if (value != -1)
return value;
}
}
// If there is no value in the properties table,
// then check for some special characters
switch (c) {
case 0x3007: return 0;
case 0x4e00: return 1;
case 0x4e8c: return 2;
case 0x4e09: return 3;
case 0x56d8: return 4;
case 0x4e94: return 5;
case 0x516d: return 6;
case 0x4e03: return 7;
case 0x516b: return 8;
case 0x4e5d: return 9;
default: return -1;
}
}
void
BUnicodeChar::ToUTF8(uint32 c, char **out)
{
char *s = *out;
if (c < 0x80)
*(s++) = c;
else if (c < 0x800) {
*(s++) = 0xc0 | (c >> 6);
*(s++) = 0x80 | (c & 0x3f);
} else if (c < 0x10000) {
*(s++) = 0xe0 | (c >> 12);
*(s++) = 0x80 | ((c >> 6) & 0x3f);
*(s++) = 0x80 | (c & 0x3f);
} else if (c <= 0x10ffff) {
*(s++) = 0xf0 | (c >> 18);
*(s++) = 0x80 | ((c >> 12) & 0x3f);
*(s++) = 0x80 | ((c >> 6) & 0x3f);
*(s++) = 0x80 | (c & 0x3f);
}
*out = s;
}
uint32
BUnicodeChar::FromUTF8(const char **in)
{
uint8 *bytes = (uint8 *)*in;
if (bytes == NULL)
return 0;
int32 length;
uint8 mask = 0x1f;
switch (bytes[0] & 0xf0) {
case 0xc0:
case 0xd0: length = 2; break;
case 0xe0: length = 3; break;
case 0xf0:
mask = 0x0f;
length = 4;
break;
default:
// valid 1-byte character
// and invalid characters
(*in)++;
return bytes[0];
}
uint32 c = bytes[0] & mask;
int32 i = 1;
for (;i < length && (bytes[i] & 0x80) > 0;i++)
c = (c << 6) | (bytes[i] & 0x3f);
if (i < length) {
// invalid character
(*in)++;
return (uint32)bytes[0];
}
*in += length;
return c;
}
size_t
BUnicodeChar::UTF8StringLength(const char *str)
{
size_t len = 0;
while (*str) {
FromUTF8(&str);
len++;
}
return len;
}
size_t
BUnicodeChar::UTF8StringLength(const char *str, size_t maxLength)
{
size_t len = 0;
while (len < maxLength && *str) {
FromUTF8(&str);
len++;
}
return len;
}

54
src/kits/locale/adler32.c Normal file
View File

@ -0,0 +1,54 @@
/* adler32.c -- compute the Adler-32 checksum of a data stream
* Copyright (C) 1995-2002 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/*
* [zooey]:
* This file has been adjusted from the original found in zlib
* for better conformance to our style-guide.
*/
#include <SupportDefs.h>
#include <LocaleBuild.h>
uint32 _IMPEXP_LOCALE adler32(uint32 adler, const uint8 *buf, uint32 len);
// prototype required by mwcc
#define BASE 65521L /* largest prime smaller than 65536 */
#define NMAX 5552
/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
#define DO1(buf,i) {s1 += buf[i]; s2 += s1;}
#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
#define DO16(buf) DO8(buf,0); DO8(buf,8);
/* ========================================================================= */
uint32 adler32(uint32 adler, const uint8 *buf, uint32 len)
{
uint32 s1 = adler & 0xffff;
uint32 s2 = (adler >> 16) & 0xffff;
int k;
if (buf == NULL) return 1L;
while (len > 0) {
k = len < NMAX ? len : NMAX;
len -= k;
while (k >= 16) {
DO16(buf);
buf += 16;
k -= 16;
}
if (k != 0) do {
s1 += *buf++;
s2 += s1;
} while (--k);
s1 %= BASE;
s2 %= BASE;
}
return (s2 << 16) | s1;
}

30
src/kits/locale/cat.cpp Normal file
View File

@ -0,0 +1,30 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <nl_types.h>
nl_catd
catopen(const char *name, int oflag)
{
return (nl_catd)1;
}
char *
catgets(nl_catd cat, int setID, int msgID, const char *defaultMessage)
{
// should return "const char *"...
return const_cast<char *>(defaultMessage);
}
int
catclose(nl_catd)
{
return 0;
}

View File

@ -0,0 +1,20 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <Locale.h>
#include <langinfo.h>
char *
nl_langinfo(nl_item id)
{
if (be_locale != NULL)
be_locale->GetString(id);
// ToDo: return default values!
return "";
}

179
src/kits/locale/makefile Normal file
View File

@ -0,0 +1,179 @@
## BeOS Generic Makefile v2.2 ##
## Fill in this file to specify the project being created, and the referenced
## makefile-engine will do all of the hard work for you. This handles both
## Intel and PowerPC builds of the BeOS.
## Application Specific Settings ---------------------------------------------
# specify the name of the binary
NAME= liblocale.so
# specify the type of binary
# APP: Application
# SHARED: Shared library or add-on
# STATIC: Static library archive
# DRIVER: Kernel Driver
TYPE= SHARED
# add support for new Pe and Eddie features
# to fill in generic makefile
#%{
# @src->@
# specify the source files to use
# full paths or paths relative to the makefile can be included
# all files, regardless of directory, will have their object
# files created in the common object directory.
# Note that this means this makefile will not work correctly
# if two source files with the same name (source.c or source.cpp)
# are included from different directories. Also note that spaces
# in folder names do not work well with this makefile.
SRCS= \
adler32.c \
cat.cpp \
Catalog.cpp \
Collator.cpp \
Country.cpp \
Currency.cpp \
DefaultCatalog.cpp \
FloatFormat.cpp \
FloatFormatImpl.cpp \
FloatFormatParameters.cpp \
Format.cpp \
FormatImpl.cpp \
FormatParameters.cpp \
GenericNumberFormat.cpp \
IntegerFormat.cpp \
IntegerFormatImpl.cpp \
IntegerFormatParameters.cpp \
langinfo.cpp \
Language.cpp \
LibraryInit.cpp \
Locale.cpp \
LocaleRoster.cpp \
NumberFormat.cpp \
NumberFormatImpl.cpp \
NumberFormatParameters.cpp \
PropertyFile.cpp \
strfmon.cpp \
UnicodeChar.cpp
# specify the resource files to use
# full path or a relative path to the resource file can be used.
RSRCS=
# @<-src@
#%}
# end support for Pe and Eddie
# specify additional libraries to link against
# there are two acceptable forms of library specifications
# - if your library follows the naming pattern of:
# libXXX.so or libXXX.a you can simply specify XXX
# library: libbe.so entry: be
#
# - if your library does not follow the standard library
# naming scheme you need to specify the path to the library
# and it's name
# library: my_lib.a entry: my_lib.a or path/my_lib.a
LIBS= be
# specify additional paths to directories following the standard
# libXXX.so or libXXX.a naming scheme. You can specify full paths
# or paths relative to the makefile. The paths included may not
# be recursive, so include all of the paths where libraries can
# be found. Directories where source files are found are
# automatically included.
LIBPATHS=
# additional paths to look for system headers
# thes use the form: #include <header>
# source file directories are NOT auto-included here
SYSTEM_INCLUDE_PATHS = ../include ../include/posix
# additional paths to look for local headers
# thes use the form: #include "header"
# source file directories are automatically included
LOCAL_INCLUDE_PATHS =
# specify the level of optimization that you desire
# NONE, SOME, FULL
OPTIMIZE= SOME
# specify any preprocessor symbols to be defined. The symbols will not
# have their values set automatically; you must supply the value (if any)
# to use. For example, setting DEFINES to "DEBUG=1" will cause the
# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG"
# would pass "-DDEBUG" on the compiler's command line.
DEFINES=
# specify special warning levels
# if unspecified default warnings will be used
# NONE = supress all warnings
# ALL = enable all warnings
WARNINGS = ALL
# specify whether image symbols will be created
# so that stack crawls in the debugger are meaningful
# if TRUE symbols will be created
SYMBOLS = TRUE
# specify debug settings
# if TRUE will allow application to be run from a source-level
# debugger. Note that this will disable all optimzation.
ifeq ($(DEBUG_BUILD), true)
DEBUGGER = TRUE
else
DEBUGGER = FALSE
endif
# specify additional compiler flags for all files
COMPILER_FLAGS =
# specify additional linker flags
LINKER_FLAGS =
# specify the version of this particular item
# (for example, -app 3 4 0 d 0 -short 340 -long "340 "`echo -n -e '\302\251'`"1999 GNU GPL")
# This may also be specified in a resource.
APP_VERSION =
# (for TYPE == DRIVER only) Specify desired location of driver in the /dev
# hierarchy. Used by the driverinstall rule. E.g., DRIVER_PATH = video/usb will
# instruct the driverinstall rule to place a symlink to your driver's binary in
# ~/add-ons/kernel/drivers/dev/video/usb, so that your driver will appear at
# /dev/video/usb when loaded. Default is "misc".
DRIVER_PATH =
#MACHINE=$(shell uname -m)
#ifneq ($(MACHINE),BePC)
# COMPILER_FLAGS += -w iserr
#else
# COMPILER_FLAGS += -Werror
#endif
# Custom overrides that can be set from the command line.
ifeq ($(DEBUG_BUILD), true)
SYMBOLS := TRUE
DEBUGGER := TRUE
OPTIMIZE := NONE
COMPILER_FLAGS += -DDEBUG=1
endif
ifeq ($(CHECK_MEM), true)
SYMBOLS := TRUE
DEBUGGER := TRUE
OPTIMIZE := NONE
COMPILER_FLAGS += -fcheck-memory-usage -DDEBUG=1 -D_NO_INLINE_ASM=1
#-D_KERNEL_MODE=1
endif
INSTALL_DIR=/boot/home/config/lib
TARGET_DIR=.
## include the makefile-engine
include $(BUILDHOME)/etc/makefile-engine

181
src/kits/locale/strfmon.cpp Normal file
View File

@ -0,0 +1,181 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <SupportDefs.h>
#include <errno.h>
#include <monetary.h>
#include <locale.h>
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
// ToDo: implementation is not yet working!
enum strfmon_flags {
USE_GROUPING = 1,
USE_SIGN = 2,
USE_LOCALE_POSNEG = 4,
NEG_IN_PARENTHESES = 8,
NO_CURRENCY = 16,
LEFT_JUSTIFIED = 32,
USE_INT_CURRENCY = 64
};
static int32
parseNumber(const char **_format)
{
const char *format = *_format;
int32 number = 0;
while (isdigit(*format))
number = number * 10 + *format++ - '0';
*_format = format;
return number;
}
ssize_t
vstrfmon(char *string, size_t maxSize, const char *format, va_list args)
{
if (format == NULL || string == NULL)
return B_BAD_VALUE;
struct lconv *lconv = localeconv();
int32 length = 0;
while (*format) {
if (format[0] != '%' || *++format == '%') {
if (++length >= (int32)maxSize)
return E2BIG;
*string++ = *format++;
continue;
}
if (format[0] == '\0')
return B_BAD_VALUE;
char flags = USE_GROUPING | USE_LOCALE_POSNEG;
char fill = ' ';
int32 width = 0, leftPrecision = 0, rightPrecision = -1;
bool isNegative = false;
// flags
int32 mode = 0;
while (*format && mode == 0) {
switch (*format++) {
case '=':
fill = *format++;
if (fill == '\0')
return B_BAD_VALUE;
break;
case '+':
if (flags & USE_SIGN)
return B_BAD_VALUE;
flags |= USE_SIGN;
break;
case '(':
if (flags & USE_SIGN)
return B_BAD_VALUE;
flags |= USE_SIGN | NEG_IN_PARENTHESES;
break;
case '^':
flags &= ~USE_GROUPING;
break;
case '!':
flags |= NO_CURRENCY;
break;
case '-':
flags |= LEFT_JUSTIFIED;
break;
default:
mode = 1;
}
}
// width
if (isdigit(*format))
width = parseNumber(&format);
// left precision
if (*format == '#') {
format++;
if (!isdigit(*format))
return B_BAD_VALUE;
leftPrecision = parseNumber(&format);
}
// right precision
if (*format == '.') {
format++;
if (!isdigit(*format))
return B_BAD_VALUE;
rightPrecision = parseNumber(&format);
}
// which currency symbol to use?
switch (*format++) {
case 'n':
// national currency symbol is the default
break;
case 'i':
flags |= USE_INT_CURRENCY;
break;
default:
return B_BAD_VALUE;
}
// adjust the default right precision value according the currency symbol
if (rightPrecision == -1) {
rightPrecision = flags & USE_INT_CURRENCY ? lconv->int_frac_digits : lconv->frac_digits;
if (rightPrecision == CHAR_MAX)
rightPrecision = 2;
}
double value = va_arg(args,double);
if (value < 0) {
isNegative = true;
value = -value;
}
if (leftPrecision + rightPrecision > 255)
return B_BAD_VALUE;
char number[256];
sprintf(number, "%*.*f", (int)leftPrecision, (int)rightPrecision,
value);
if (leftPrecision >= 0) {
}
}
return B_OK;
}
ssize_t
strfmon(char *string, size_t maxSize, const char *format, ...)
{
va_list args;
va_start(args, format);
ssize_t status = vstrfmon(string, maxSize, format, args);
va_end(args);
if (status < B_OK) {
errno = status;
return -1;
}
return status;
}

View File

@ -0,0 +1,8 @@
SubDir LOCALE_TOP preferences ;
AddResources Locale : Locale.rsrc ;
Application Locale :
Locale.cpp
LocaleWindow.cpp
: be liblocale.so ;

View File

@ -0,0 +1,198 @@
/*
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "Locale.h"
#include "LocaleWindow.h"
#include <Application.h>
#include <Alert.h>
#include <TextView.h>
#include <FindDirectory.h>
#include <File.h>
#include <Path.h>
#include <stdio.h>
#include <string.h>
const char *kSignature = "application/x-vnd.Haiku-Locale";
static const uint32 kMsgLocaleSettings = 'LCst';
class Settings {
public:
Settings();
~Settings();
const BMessage &Message() const { return fMessage; }
void UpdateFrom(BMessage *message);
private:
status_t Open(BFile *file, int32 mode);
BMessage fMessage;
bool fUpdated;
};
class Locale : public BApplication {
public:
Locale();
virtual ~Locale();
virtual void ReadyToRun();
virtual void MessageReceived(BMessage *message);
virtual void AboutRequested();
virtual bool QuitRequested();
private:
Settings fSettings;
BWindow *fOpenWindow;
BRect fWindowFrame;
};
//-----------------
Settings::Settings()
:
fMessage(kMsgLocaleSettings),
fUpdated(false)
{
BFile file;
if (Open(&file, B_READ_ONLY) != B_OK
|| fMessage.Unflatten(&file) != B_OK) {
// set default prefs
fMessage.AddRect("window_frame", BRect(50, 50, 550, 500));
return;
}
}
Settings::~Settings()
{
// only save the settings if something has changed
if (!fUpdated)
return;
BFile file;
if (Open(&file, B_CREATE_FILE | B_WRITE_ONLY) != B_OK)
return;
fMessage.Flatten(&file);
}
status_t
Settings::Open(BFile *file, int32 mode)
{
BPath path;
if (find_directory(B_USER_SETTINGS_DIRECTORY, &path) != B_OK)
return B_ERROR;
path.Append("Locale settings");
return file->SetTo(path.Path(), mode);
}
void
Settings::UpdateFrom(BMessage *message)
{
BRect frame;
if (message->FindRect("window_frame", &frame) == B_OK)
fMessage.ReplaceRect("window_frame", frame);
fUpdated = true;
}
// #pragma mark -
Locale::Locale()
: BApplication(kSignature)
{
fWindowFrame = fSettings.Message().FindRect("window_frame");
BWindow* window = new LocaleWindow(fWindowFrame);
window->Show();
}
Locale::~Locale()
{
}
void
Locale::ReadyToRun()
{
// are there already windows open?
if (CountWindows() != 1)
return;
// if not, ask the user to open a file
PostMessage(kMsgOpenOpenWindow);
}
void
Locale::MessageReceived(BMessage *message)
{
switch (message->what) {
case kMsgSettingsChanged:
fSettings.UpdateFrom(message);
break;
default:
BApplication::MessageReceived(message);
break;
}
}
void
Locale::AboutRequested()
{
BAlert *alert = new BAlert("about", "Locale\n"
"\twritten by Axel Dörfler\n"
"\tCopyright 2005, Haiku.\n\n", "Ok");
BTextView *view = alert->TextView();
BFont font;
view->SetStylable(true);
view->GetFont(&font);
font.SetSize(18);
font.SetFace(B_BOLD_FACE);
view->SetFontAndColor(0, 7, &font);
alert->Go();
}
bool
Locale::QuitRequested()
{
return true;
}
// #pragma mark -
int
main(int argc, char **argv)
{
Locale app;
app.Run();
return 0;
}

View File

@ -0,0 +1,25 @@
/*
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef LOCALE_H
#define LOCALE_H
#include <SupportDefs.h>
extern const char *kSignature;
static const uint32 kMsgOpenFilePanel = 'opFp';
static const uint32 kMsgOpenOpenWindow = 'opOw';
static const uint32 kMsgOpenWindowClosed = 'clOw';
static const uint32 kMsgWindowClosed = 'WiCl';
static const uint32 kMsgSettingsChanged = 'SeCh';
static const uint32 kMsgOpenFindWindow = 'OpFw';
static const uint32 kMsgFindWindowClosed = 'clFw';
static const uint32 kMsgFindTarget = 'FTgt';
static const uint32 kMsgFind = 'find';
#endif /* LOCALE_H */

View File

@ -0,0 +1,125 @@
/*
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#include "Locale.h"
#include "LocaleWindow.h"
#include <Application.h>
#include <Screen.h>
#include <TabView.h>
#include <ScrollView.h>
#include <ListView.h>
#include <Button.h>
const static uint32 kMsgSelectLanguage = 'slng';
const static uint32 kMsgDefaults = 'dflt';
const static uint32 kMsgRevert = 'revt';
LocaleWindow::LocaleWindow(BRect rect)
: BWindow(rect, "Locale", B_TITLED_WINDOW,
B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_ASYNCHRONOUS_CONTROLS)
{
rect = Bounds();
BView *view = new BView(rect, "view", B_FOLLOW_ALL, 0);
view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));
AddChild(view);
BButton *button = new BButton(rect, "defaults", "Defaults",
new BMessage(kMsgDefaults), B_FOLLOW_NONE);
button->ResizeToPreferred();
button->MoveTo(10, rect.bottom - 10 - button->Bounds().Height());
view->AddChild(button);
fRevertButton = new BButton(rect, "revert", "Revert",
new BMessage(kMsgRevert), B_FOLLOW_NONE);
fRevertButton->ResizeToPreferred();
fRevertButton->MoveTo(20 + button->Bounds().Width(), button->Frame().top);
fRevertButton->SetEnabled(false);
view->AddChild(fRevertButton);
rect.InsetBy(10, 10);
rect.bottom -= 10 + button->Bounds().Height();
BTabView *tabView = new BTabView(rect, "tabview");
rect = tabView->ContainerView()->Bounds();
rect.InsetBy(2, 2);
BView *tab = new BView(rect, "Language", B_FOLLOW_NONE, B_WILL_DRAW);
tab->SetViewColor(tabView->ViewColor());
tabView->AddTab(tab);
{
BRect frame = rect;
frame.InsetBy(12, 12);
frame.right = 100 + B_V_SCROLL_BAR_WIDTH;
frame.bottom = 150;
BListView *listView = new BListView(frame, "preferred", B_SINGLE_SELECTION_LIST,
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP);
listView->SetSelectionMessage(new BMessage(kMsgSelectLanguage));
BScrollView *scrollView = new BScrollView("scroller", listView,
B_FOLLOW_LEFT_RIGHT | B_FOLLOW_TOP, 0, false, true, B_FANCY_BORDER);
tab->AddChild(scrollView);
}
tab = new BView(rect, "Country", B_FOLLOW_NONE, B_WILL_DRAW);
tab->SetViewColor(tabView->ViewColor());
tabView->AddTab(tab);
tab = new BView(rect, "Keyboard", B_FOLLOW_NONE, B_WILL_DRAW);
tab->SetViewColor(tabView->ViewColor());
tabView->AddTab(tab);
view->AddChild(tabView);
// check if the window is on screen
rect = BScreen().Frame();
rect.right -= 20;
rect.bottom -= 20;
BPoint position = Frame().LeftTop();
if (!rect.Contains(position)) {
// center window on screen as it doesn't fit on the saved position
position.x = (rect.Width() - Bounds().Width()) / 2;
position.y = (rect.Height() - Bounds().Height()) / 2;
}
MoveTo(position);
}
bool
LocaleWindow::QuitRequested()
{
BMessage update(kMsgSettingsChanged);
update.AddRect("window_frame", Frame());
be_app_messenger.SendMessage(&update);
be_app_messenger.SendMessage(B_QUIT_REQUESTED);
return true;
}
void
LocaleWindow::MessageReceived(BMessage *message)
{
switch (message->what) {
case kMsgDefaults:
// reset default settings
break;
case kMsgRevert:
// revert to last settings
break;
default:
BWindow::MessageReceived(message);
break;
}
}

View File

@ -0,0 +1,25 @@
/*
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef LOCALE_WINDOW_H
#define LOCALE_WINDOW_H
#include <Window.h>
class BButton;
class LocaleWindow : public BWindow {
public:
LocaleWindow(BRect rect);
virtual bool QuitRequested();
virtual void MessageReceived(BMessage *message);
private:
BButton* fRevertButton;
};
#endif /* LOCALE_WINDOW_H */

View File

@ -0,0 +1,28 @@
SubDir LOCALE_TOP test ;
rule SimpleTest
{
# SimpleTest <sources> ;
local sources = $(1) ;
local name = $(sources[1]:B) ;
Application $(name) : $(sources) : be liblocale.so ;
}
SimpleTest localeTest.cpp ;
SimpleTest collatorTest.cpp ;
SimpleTest collatorSpeed.cpp ;
SimpleTest catalogTest.cpp ;
AddOn catalogTestAddOn : catalogTestAddOn.cpp : be liblocale.so ;
SimpleTest catalogSpeed.cpp ;
SimpleTest genericNumberFormatTest.cpp ;
# For the unit tests we need liblocale.so to live in the `lib' subdirectory
# of the UnitTester application. We simply create a symlink that can be
# referred to by `<unittests>liblocale.so'.
{
local symlink = <unittests>liblocale.so ;
MakeLocate $(symlink) : [ FDirName $(LOCALE_UNITTESTS_DIR) lib ] ;
RelSymLink $(symlink) : liblocale.so ;
}
SubInclude LOCALE_TOP test number_format ;

View File

@ -0,0 +1,204 @@
/*
** Copyright 2003, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <assert.h>
#include <stdio.h>
#include <typeinfo>
#include <unistd.h>
#include <Application.h>
#include <StopWatch.h>
#include <Catalog.h>
#include <DefaultCatalog.h>
#include <Entry.h>
#include <Locale.h>
#include <Path.h>
#include <Roster.h>
const uint32 kNumStrings = 10000;
BString strs[kNumStrings];
BString ctxs[kNumStrings];
BString trls[kNumStrings];
const char *translated;
class CatalogSpeed {
public:
void TestCreation();
void TestLookup();
void TestIdCreation();
void TestIdLookup();
};
#define TR_CONTEXT "CatalogSpeed"
#define catSig "x-vnd.Be.locale.catalogSpeed"
#define catName catSig".catalog"
void
CatalogSpeed::TestCreation()
{
for (uint32 i = 0; i < kNumStrings; i++) {
strs[i] << "native-string#" << 1000000+i;
ctxs[i] << TR_CONTEXT;
trls[i] << "translation#" << 4000000+i;
}
BStopWatch watch("catalogSpeed", true);
status_t res;
assert(be_locale != NULL);
system("mkdir -p ./locale/catalogs/"catSig);
// create an empty catalog of default type...
BPrivate::EditableCatalog cat1("Default", catSig, "klingon");
assert(cat1.InitCheck() == B_OK);
// ...and populate the catalog with some data:
for (uint32 i = 0; i < kNumStrings; i++) {
cat1.SetString(strs[i].String(), trls[i].String(), ctxs[i].String());
}
watch.Suspend();
printf("\tadded %ld strings in %9Ld usecs\n",
cat1.CountItems(), watch.ElapsedTime());
watch.Reset();
watch.Resume();
res = cat1.WriteToFile("./locale/catalogs/"catSig"/klingon.catalog");
assert(res == B_OK);
watch.Suspend();
printf("\t%ld strings written to disk in %9Ld usecs\n",
cat1.CountItems(), watch.ElapsedTime());
}
void
CatalogSpeed::TestLookup()
{
BStopWatch watch("catalogSpeed", true);
BCatalog *cat = be_catalog = new BCatalog(catSig, "klingon");
assert(cat != NULL);
assert(cat->InitCheck() == B_OK);
watch.Suspend();
printf("\t%ld strings read from disk in %9Ld usecs\n",
cat->CountItems(), watch.ElapsedTime());
watch.Reset();
watch.Resume();
for (uint32 i = 0; i < kNumStrings; i++) {
translated = TR(strs[i].String());
}
watch.Suspend();
printf("\tlooked up %lu strings in %9Ld usecs\n",
kNumStrings, watch.ElapsedTime());
delete cat;
}
void
CatalogSpeed::TestIdCreation()
{
BStopWatch watch("catalogSpeed", true);
watch.Suspend();
status_t res;
BString s("string");
s << "\x01" << typeid(*this).name() << "\x01";
//size_t hashVal = __stl_hash_string(s.String());
assert(be_locale != NULL);
system("mkdir -p ./locale/catalogs/"catSig);
// create an empty catalog of default type...
BPrivate::EditableCatalog cat1("Default", catSig, "klingon");
assert(cat1.InitCheck() == B_OK);
// ...and populate the catalog with some data:
for (uint32 i = 0; i < kNumStrings; i++) {
trls[i] = BString("id_translation#") << 6000000+i;
}
watch.Reset();
watch.Resume();
for (uint32 i = 0; i < kNumStrings; i++) {
cat1.SetString(i, trls[i].String());
}
watch.Suspend();
printf("\tadded %ld strings by id in %9Ld usecs\n",
cat1.CountItems(), watch.ElapsedTime());
watch.Reset();
watch.Resume();
res = cat1.WriteToFile("./locale/catalogs/"catSig"/klingon.catalog");
assert( res == B_OK);
watch.Suspend();
printf("\t%ld strings written to disk in %9Ld usecs\n",
cat1.CountItems(), watch.ElapsedTime());
}
void
CatalogSpeed::TestIdLookup()
{
BStopWatch watch("catalogSpeed", true);
BCatalog *cat = be_catalog = new BCatalog(catSig, "klingon");
assert(cat != NULL);
assert(cat->InitCheck() == B_OK);
watch.Suspend();
printf("\t%ld strings read from disk in %9Ld usecs\n",
cat->CountItems(), watch.ElapsedTime());
watch.Reset();
watch.Resume();
for (uint32 i = 0; i < kNumStrings; i++) {
translated = TR_ID(i);
}
watch.Suspend();
printf("\tlooked up %lu strings in %9Ld usecs\n",
kNumStrings, watch.ElapsedTime());
delete cat;
}
int
main(int argc, char **argv)
{
BApplication* testApp
= new BApplication("application/"catSig);
// change to app-folder:
app_info appInfo;
be_app->GetAppInfo(&appInfo);
BEntry appEntry(&appInfo.ref);
BEntry appFolder;
appEntry.GetParent(&appFolder);
BPath appPath;
appFolder.GetPath(&appPath);
chdir(appPath.Path());
CatalogSpeed catSpeed;
printf("\t------------------------------------------------\n");
printf("\tstring-based catalog usage:\n");
printf("\t------------------------------------------------\n");
catSpeed.TestCreation();
catSpeed.TestLookup();
printf("\t------------------------------------------------\n");
printf("\tid-based catalog usage:\n");
printf("\t------------------------------------------------\n");
catSpeed.TestIdCreation();
catSpeed.TestIdLookup();
delete testApp;
return 0;
}

View File

@ -0,0 +1,197 @@
/*
** Copyright 2003, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <assert.h>
#include <stdio.h>
#include <unistd.h>
#include <Application.h>
#include <Catalog.h>
#include <DefaultCatalog.h>
#include <Entry.h>
#include <Locale.h>
#include <Path.h>
#include <Roster.h>
class CatalogTest {
public:
void Run();
void Check();
};
#define TR_CONTEXT "CatalogTest"
#define catSig "x-vnd.Be.locale.catalogTest"
#define catName catSig".catalog"
void
CatalogTest::Run()
{
printf("app...");
status_t res;
BString s;
s << "string" << "\x01" << TR_CONTEXT << "\x01";
size_t hashVal = CatKey::HashFun(s.String());
assert(be_locale != NULL);
system("mkdir -p ./locale/catalogs/"catSig);
// create an empty catalog of default type...
BPrivate::EditableCatalog cata("Default", catSig, "German");
assert(cata.InitCheck() == B_OK);
// ...and populate the catalog with some data:
res = cata.SetString("string", "Schnur", TR_CONTEXT);
assert(res == B_OK);
res = cata.SetString(hashVal, "Schnur_id");
// add a second entry for the same hash-value, but with different
// translation
assert(res == B_OK);
res = cata.SetString("string", "String", "programming");
assert(res == B_OK);
res = cata.SetString("string", "Textpuffer", "programming",
"Deutsches Fachbuch");
assert(res == B_OK);
res = cata.SetString("string", "Leine", TR_CONTEXT, "Deutsches Fachbuch");
assert(res == B_OK);
res = cata.WriteToFile("./locale/catalogs/"catSig"/german.catalog");
assert(res == B_OK);
// check if we are getting back the correct strings:
s = cata.GetString(("string"), TR_CONTEXT);
assert(s == "Schnur");
s = cata.GetString(hashVal);
assert(s == "Schnur_id");
s = cata.GetString("string", "programming");
assert(s == "String");
s = cata.GetString("string", "programming", "Deutsches Fachbuch");
assert(s == "Textpuffer");
s = cata.GetString("string", TR_CONTEXT, "Deutsches Fachbuch");
assert(s == "Leine");
// now we create a new (base) catalog and embed this one into the app-file:
BPrivate::EditableCatalog catb("Default", catSig, "English");
assert(catb.InitCheck() == B_OK);
// the following string is unique to the embedded catalog:
res = catb.SetString("string", "string", "base");
assert(res == B_OK);
// the following id is unique to the embedded catalog:
res = catb.SetString(32, "hashed string");
assert(res == B_OK);
// the following string will be hidden by the definition inside the
// german catalog:
res = catb.SetString("string", "hidden", TR_CONTEXT);
assert(res == B_OK);
app_info appInfo;
res = be_app->GetAppInfo(&appInfo);
assert(res == B_OK);
// embed created catalog into application file (catalogTest):
res = catb.WriteToResource(&appInfo.ref);
assert(res == B_OK);
printf("ok.\n");
Check();
}
void
CatalogTest::Check()
{
status_t res;
printf("app-check...");
BString s;
s << "string" << "\x01" << TR_CONTEXT << "\x01";
size_t hashVal = CatKey::HashFun(s.String());
// ok, we now try to re-load the catalog that has just been written:
//
// actually, the following code can be seen as an example of what an
// app needs in order to translate strings:
BCatalog cat;
res = be_locale->GetAppCatalog(&cat);
assert(res == B_OK);
// fetch basic data:
int32 fingerprint;
res = cat.GetFingerprint(&fingerprint);
assert(res == B_OK);
BString lang;
res = cat.GetLanguage(&lang);
assert(res == B_OK);
BString sig;
res = cat.GetSignature(&sig);
assert(res == B_OK);
// now check strings:
s = TR_ID(hashVal);
assert(s == "Schnur_id");
s = TR_ALL("string", "programming", "");
assert(s == "String");
s = TR_ALL("string", "programming", "Deutsches Fachbuch");
assert(s == "Textpuffer");
s = TR_CMT("string", "Deutsches Fachbuch");
assert(s == "Leine");
// the following string should be found in the embedded catalog only:
s = TR_ALL("string", "base", NULL);
assert(s == "string");
// the following id should be found in the embedded catalog only:
s = TR_ID(32);
assert(s == "hashed string");
// the following id doesn't exist anywhere (hopefully):
s = TR_ID(-1);
assert(s == "");
// the following string exists twice, in the embedded as well as in the
// external catalog. So we should get the external translation (as it should
// override the embedded one):
s = TR("string");
assert(s == "Schnur");
// now check if trying to access same catalog by specifying its data works:
BCatalog cat2(sig.String(), lang.String(), fingerprint);
assert(cat2.InitCheck() == B_OK);
// now check if trying to access same catalog with wrong fingerprint fails:
BCatalog cat3(sig.String(), lang.String(), fingerprint*-1);
assert(cat3.InitCheck() == B_NO_INIT);
// translating through an invalid catalog should yield the native string:
s = cat3.GetString("string");
assert(s == "string");
printf("ok.\n");
}
int
main(int argc, char **argv)
{
BApplication* testApp
= new BApplication("application/"catSig);
// change to app-folder:
app_info appInfo;
be_app->GetAppInfo(&appInfo);
BEntry appEntry(&appInfo.ref);
BEntry appFolder;
appEntry.GetParent( &appFolder);
BPath appPath;
appFolder.GetPath( &appPath);
chdir( appPath.Path());
CatalogTest catTest;
catTest.Run();
char cwd[B_FILE_NAME_LENGTH];
getcwd(cwd, B_FILE_NAME_LENGTH);
BString addonName(cwd);
addonName << "/" "catalogTestAddOn";
image_id image = load_add_on(addonName.String());
assert(image >= B_OK);
void (*runAddonFunc)() = 0;
get_image_symbol(image, "run_test_add_on",
B_SYMBOL_TYPE_TEXT, (void **)&runAddonFunc);
assert(runAddonFunc);
runAddonFunc();
catTest.Check();
delete testApp;
}

View File

@ -0,0 +1,158 @@
/*
** Copyright 2003, Oliver Tappe, zooey@hirschkaefer.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <assert.h>
#include <stdio.h>
#include <CatalogInAddOn.h>
#include <DefaultCatalog.h>
class CatalogTestAddOn {
public:
void Run();
void Check();
};
#define TR_CONTEXT "CatalogTestAddOn"
#define catSig "add-ons/catalogTest/catalogTestAddOn"
#define catName catSig".catalog"
void
CatalogTestAddOn::Run() {
printf("addon...");
status_t res;
BString s;
s << "string" << "\x01" << TR_CONTEXT << "\x01";
size_t hashVal = CatKey::HashFun(s.String());
assert(be_locale != NULL);
system("mkdir -p ./locale/catalogs/"catSig);
// create an empty catalog of default type...
BPrivate::EditableCatalog cat1("Default", catSig, "German");
assert(cat1.InitCheck() == B_OK);
// ...and populate the catalog with some data:
res = cat1.SetString("string", "Schnur_A", TR_CONTEXT);
assert(res == B_OK);
res = cat1.SetString(hashVal, "Schnur_id_A");
// add a second entry for the same hash-value, but with different translation
assert(res == B_OK);
res = cat1.SetString("string", "String_A", "programming");
assert(res == B_OK);
res = cat1.SetString("string", "Textpuffer_A", "programming", "Deutsches Fachbuch");
assert(res == B_OK);
res = cat1.SetString("string", "Leine_A", TR_CONTEXT, "Deutsches Fachbuch");
assert(res == B_OK);
res = cat1.WriteToFile("./locale/catalogs/"catSig"/german.catalog");
assert(res == B_OK);
// check if we are getting back the correct strings:
s = cat1.GetString("string", TR_CONTEXT);
assert(s == "Schnur_A");
s = cat1.GetString(hashVal);
assert(s == "Schnur_id_A");
s = cat1.GetString("string", "programming");
assert(s == "String_A");
s = cat1.GetString("string", "programming", "Deutsches Fachbuch");
assert(s == "Textpuffer_A");
s = cat1.GetString("string", TR_CONTEXT, "Deutsches Fachbuch");
assert(s == "Leine_A");
// now we create a new (base) catalog and embed this one into the add-on-file:
BPrivate::EditableCatalog cat2("Default", catSig, "English");
assert(cat2.InitCheck() == B_OK);
// the following string is unique to the embedded catalog:
res = cat2.SetString("string", "string_A", "base");
assert(res == B_OK);
// the following id is unique to the embedded catalog:
res = cat2.SetString(32, "hashed string_A");
assert(res == B_OK);
// the following string will be hidden by the definition inside the german catalog:
res = cat2.SetString("string", "hidden_A", TR_CONTEXT);
assert(res == B_OK);
entry_ref addOnRef;
res = get_add_on_ref(&addOnRef);
assert(res == B_OK);
res = cat2.WriteToResource(&addOnRef);
assert(res == B_OK);
printf("ok.\n");
Check();
}
void
CatalogTestAddOn::Check() {
status_t res;
printf("addon-check...");
BString s;
s << "string" << "\x01" << TR_CONTEXT << "\x01";
size_t hashVal = CatKey::HashFun(s.String());
// ok, we now try to re-load the catalog that has just been written:
//
// actually, the following code can be seen as an example of what an
// add_on needs in order to translate strings:
BCatalog cat;
res = get_add_on_catalog(&cat, catSig);
assert(res == B_OK);
// fetch basic data:
int32 fingerprint;
res = cat.GetFingerprint(&fingerprint);
assert(res == B_OK);
BString lang;
res = cat.GetLanguage(&lang);
assert(res == B_OK);
assert(lang == "german");
BString sig;
res = cat.GetSignature(&sig);
assert(res == B_OK);
assert(sig == catSig);
// now check strings:
s = TR_ID(hashVal);
assert(s == "Schnur_id_A");
s = TR_ALL("string", "programming", "");
assert(s == "String_A");
s = TR_ALL("string", "programming", "Deutsches Fachbuch");
assert(s == "Textpuffer_A");
s = TR_CMT("string", "Deutsches Fachbuch");
assert(s == "Leine_A");
// the following string should be found in the embedded catalog only:
s = TR_ALL("string", "base", "");
assert(s == "string_A");
// the following id should be found in the embedded catalog only:
s = TR_ID(32);
assert(s == "hashed string_A");
// the following id doesn't exist anywhere (hopefully):
s = TR_ID(-1);
assert(s == "");
// the following string exists twice, in the embedded as well as in the
// external catalog. So we should get the external translation (as it should
// override the embedded one):
s = TR("string");
assert(s == "Schnur_A");
// check access to app-catalog from inside add-on:
BCatalog appCat;
res = be_locale->GetAppCatalog(&appCat);
assert(res == B_OK);
s = be_app_catalog->GetString("string", "CatalogTest");
assert(s == "Schnur");
s = be_app_catalog->GetString("string", "CatalogTest", "Deutsches Fachbuch");
assert(s == "Leine");
s = be_app_catalog->GetString("string", "programming", "Deutsches Fachbuch");
assert(s == "Textpuffer");
printf("ok.\n");
}
extern "C" _EXPORT void run_test_add_on()
{
CatalogTestAddOn catTest;
catTest.Run();
}

View File

@ -0,0 +1,138 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <Collator.h>
#include <Locale.h>
#include <StopWatch.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
const char *kStrings[] = {
"a-b-c",
"a b c",
"A.b.c",
"ä,b,c",
"abc",
"gehen",
"géhen",
"aus",
"äUß",
"auss",
"WO",
"",
"SO",
"so",
"açñ",
"acn",
"pêche",
"pêché",
"peché",
"peche",
"pecher",
"eñe",
"ene",
"nz",
"ña",
"llamar",
"luz",
};
const uint32 kNumStrings = sizeof(kStrings) / sizeof(kStrings[0]);
const uint32 kIterations = 50000;
void
test(BCollator *collator, const char *name, int8 strength)
{
collator->SetDefaultStrength(strength);
BStopWatch watch(name, true);
for (uint32 j = 0; j < kIterations; j++) {
for (uint32 i = 0; i < kNumStrings; i++) {
BString key;
collator->GetSortKey(kStrings[i], &key);
}
}
watch.Suspend();
double secs = watch.ElapsedTime() / 1000000.0;
printf("\t%s%9Ld usecs, %6.3g secs,%9lu keys/s\n",
name, watch.ElapsedTime(), secs, uint32(kIterations * kNumStrings / secs));
}
void
usage()
{
fprintf(stderr,
"usage: collatorSpeed [-i] [<add-on path>]\n"
" -i\tignore punctuation (defaults to: punctuation matters)\n");
exit(-1);
}
int
main(int argc, char **argv)
{
// Parse command line arguments
bool ignorePunctuation = false;
char *addon = NULL;
BCollator *collator = NULL;
while ((++argv)[0]) {
if (argv[0][0] == '-') {
if (!strcmp(argv[0], "-i"))
ignorePunctuation = true;
else if (!strcmp(argv[0], "--help"))
usage();
} else {
// this will be the add-on to be loaded
addon = argv[0];
}
}
// load the collator add-on if necessary
if (addon != NULL) {
image_id image = load_add_on(addon);
if (image < B_OK)
fprintf(stderr, "could not load add-on at \"%s\": %s.\n", addon, strerror(image));
BCollatorAddOn *(*instantiate)(void);
if (get_image_symbol(image, "instantiate_collator",
B_SYMBOL_TYPE_TEXT, (void **)&instantiate) == B_OK) {
BCollatorAddOn *collatorAddOn = instantiate();
if (collatorAddOn != NULL)
collator = new BCollator(collatorAddOn, B_COLLATE_PRIMARY, true);
} else if (image >= B_OK) {
fprintf(stderr, "could not find instantiate_collator() function in add-on!\n");
unload_add_on(image);
}
}
if (collator == NULL) {
collator = be_locale->Collator();
addon = "default";
}
// test key creation speed
collator->SetIgnorePunctuation(ignorePunctuation);
printf("%s:\n", addon);
test(collator, "primary: ", B_COLLATE_PRIMARY);
test(collator, "secondary: ", B_COLLATE_SECONDARY);
test(collator, "tertiary: ", B_COLLATE_TERTIARY);
test(collator, "quaternary:", B_COLLATE_QUATERNARY);
test(collator, "identical: ", B_COLLATE_IDENTICAL);
return 0;
}

View File

@ -0,0 +1,210 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <Collator.h>
#include <Locale.h>
#include <Message.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
const char *kStrings[] = {
"a-b-c",
"a b c",
"A.b.c",
"ä,b,c",
"abc",
"gehen",
"géhen",
"aus",
"äUß",
"auss",
"WO",
"",
"SO",
"so",
"açñ",
"acn",
"pêche",
"pêché",
"peché",
"peche",
"PECHE",
"PÊCHE",
"pecher",
"eñe",
"ene",
"nz",
"ña",
"llamar",
"luz",
};
const uint32 kNumStrings = sizeof(kStrings) / sizeof(kStrings[0]);
BCollator *gCollator;
bool gTestKeyGeneration = true;
bool gShowKeys = false;
int
compareStrings(const void *_a, const void *_b)
{
const char *a = *(const char **)_a;
const char *b = *(const char **)_b;
return gCollator->Compare(a, b);
}
void
printArray(const char *label, const char **strings, size_t size)
{
puts(label);
uint32 bucket = 1;
for (uint32 i = 0; i < size; i++) {
if (i > 0) {
int compare = gCollator->Compare(strings[i], strings[i - 1]);
if (compare > 0)
printf("\n%2lu)", bucket++);
else if (compare < 0) {
printf("\t*** broken sort order!\n");
exit(-1);
}
// Test sort key generation
if (gTestKeyGeneration) {
BString a, b;
gCollator->GetSortKey(strings[i - 1], &a);
gCollator->GetSortKey(strings[i], &b);
int keyCompare = strcmp(a.String(), b.String());
if (keyCompare > 0 || (keyCompare == 0 && compare != 0))
printf(" (*** \"%s\" wrong keys \"%s\" ***) ", a.String(), b.String());
}
} else
printf("%2lu)", bucket++);
printf("\t%s", strings[i]);
if (gShowKeys) {
BString key;
gCollator->GetSortKey(strings[i], &key);
printf(" (%s)", key.String());
}
}
putchar('\n');
}
void
usage()
{
fprintf(stderr,
"usage: collatorTest [-ick] [<add-on path>]\n"
" -i\tignore punctuation (defaults to: punctuation matters)\n"
" -c\tcomparison only, no sort key test\n"
" -k\tshows the sort keys along the strings (sort keys doesn't have to be visually correct)\n");
exit(-1);
}
int
main(int argc, char **argv)
{
// Parse command line arguments
int strength = B_COLLATE_SECONDARY;
bool ignorePunctuation = false;
char *addon = NULL;
while ((++argv)[0]) {
if (argv[0][0] == '-' && argv[0][1] != '-') {
char *arg = argv[0] + 1;
char c;
while ((c = *arg++)) {
if (c == 'i')
ignorePunctuation = true;
else if (c == 'c')
gTestKeyGeneration = false;
else if (c == 'k')
gShowKeys = true;
else if (isdigit(c)) {
int strength = c - '0';
if (strength < B_COLLATE_PRIMARY)
strength = B_COLLATE_PRIMARY;
else if (strength > B_COLLATE_IDENTICAL)
strength = B_COLLATE_IDENTICAL;
}
}
} else if (!strcmp(argv[0], "--help")) {
usage();
} else {
// this will be the add-on to be loaded
addon = argv[0];
}
}
// load the collator add-on if necessary
if (addon != NULL) {
image_id image = load_add_on(addon);
if (image < B_OK)
fprintf(stderr, "could not load add-on at \"%s\": %s.\n", addon, strerror(image));
BCollatorAddOn *(*instantiate)(void);
if (get_image_symbol(image, "instantiate_collator",
B_SYMBOL_TYPE_TEXT, (void **)&instantiate) == B_OK) {
BCollatorAddOn *collator = instantiate();
if (collator != NULL)
gCollator = new BCollator(collator, strength, true);
} else if (image >= B_OK) {
fprintf(stderr, "could not find instantiate_collator() function in add-on!\n");
unload_add_on(image);
}
}
if (gCollator == NULL) {
printf("--------- Use standard collator! -----------\n");
gCollator = be_locale->Collator();
}
// test archiving/unarchiving collator
BMessage archive;
if (gCollator->Archive(&archive, true) != B_OK)
fprintf(stderr, "Archiving failed!\n");
else {
BArchivable *unarchived = instantiate_object(&archive);
gCollator = dynamic_cast<BCollator *>(unarchived);
if (gCollator == NULL) {
fprintf(stderr, "Unarchiving failed!\n");
delete unarchived;
gCollator = be_locale->Collator();
}
}
// test the BCollator::Compare() and GetSortKey() methods
const char *strengthLabels[] = {"primary: ", "secondary:", "tertiary: "};
uint32 strengths[] = {B_COLLATE_PRIMARY, B_COLLATE_SECONDARY, B_COLLATE_TERTIARY};
gCollator->SetIgnorePunctuation(ignorePunctuation);
for (uint32 i = 0; i < sizeof(strengths) / sizeof(strengths[0]); i++) {
gCollator->SetDefaultStrength(strengths[i]);
qsort(kStrings, kNumStrings, sizeof(char *), compareStrings);
printArray(strengthLabels[i], kStrings, kNumStrings);
}
}

View File

@ -0,0 +1,106 @@
/*
** Copyright 2004, Ingo Weinhold, bonefish@cs.tu-berlin.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include <stdio.h>
#include <string.h>
#include <GenericNumberFormat.h>
#include <IntegerFormatParameters.h>
void
format_integer(const char *test, const BGenericNumberFormat &format,
const BIntegerFormatParameters *parameters, int64 number)
{
const int bufferSize = 1024;
char buffer[bufferSize];
status_t error = format.FormatInteger(parameters, number, buffer,
bufferSize);
if (error == B_OK)
printf("%-20s `%s'\n", test, buffer);
else
printf("%-20s Failed to format number: %s\n", test, strerror(error));
}
void
format_integer(BGenericNumberFormat &format, int64 number)
{
printf("number: %lld\n", number);
BIntegerFormatParameters parameters(
format.DefaultIntegerFormatParameters());
format_integer(" default:", format, &parameters, number);
parameters.SetFormatWidth(25);
format_integer(" right aligned:", format, &parameters, number);
parameters.SetAlignment(B_ALIGN_FORMAT_LEFT);
format_integer(" left aligned:", format, &parameters, number);
parameters.SetFormatWidth(1);
parameters.SetAlignment(B_ALIGN_FORMAT_RIGHT);
parameters.SetSignPolicy(B_USE_POSITIVE_SIGN);
format_integer(" use plus:", format, &parameters, number);
parameters.SetSignPolicy(B_USE_SPACE_FOR_POSITIVE_SIGN);
format_integer(" space for plus:", format, &parameters, number);
parameters.SetSignPolicy(B_USE_NEGATIVE_SIGN_ONLY);
parameters.SetMinimalIntegerDigits(0);
format_integer(" min digits 0:", format, &parameters, number);
parameters.SetMinimalIntegerDigits(5);
format_integer(" min digits 5:", format, &parameters, number);
parameters.SetMinimalIntegerDigits(20);
format_integer(" min digits 20:", format, &parameters, number);
parameters.SetMinimalIntegerDigits(30);
format_integer(" min digits 30:", format, &parameters, number);
}
void
format_float(const char *test, const BGenericNumberFormat &format,
const BFloatFormatParameters *parameters, double number)
{
const int bufferSize = 1024;
char buffer[bufferSize];
status_t error = format.FormatFloat(parameters, number, buffer, bufferSize);
if (error == B_OK)
printf("%-20s `%s'\n", test, buffer);
else
printf("%-20s Failed to format number: %s\n", test, strerror(error));
}
void
format_float(BGenericNumberFormat &format, double number)
{
printf("number: %g\n", number);
BFloatFormatParameters parameters( format.DefaultFloatFormatParameters());
format_float(" default:", format, &parameters, number);
}
int
main()
{
BGenericNumberFormat format;
printf("Integer\n");
printf("=======\n\n");
format_integer(format, 0);
format_integer(format, 1234567890LL);
format_integer(format, -1234567890LL);
format.DefaultIntegerFormatParameters()->SetUseGrouping(true);
format_integer(format, 0);
format_integer(format, 1234567890LL);
format_integer(format, -1234567890LL);
printf("\n\nFloat\n");
printf("=====\n\n");
format_float(format, 0.0);
format_float(format, -0.0);
format_float(format, 1234567890.0);
format_float(format, -1234567890.0);
format_float(format, 1234.56789);
format_float(format, -1234.56789);
format.DefaultFloatFormatParameters()->SetUseGrouping(true);
format_float(format, 0.0);
format_float(format, -0.0);
format_float(format, 1234567890.0);
format_float(format, -1234567890.0);
format_float(format, 1234.56789);
format_float(format, -1234.56789);
return 0;
}

View File

@ -0,0 +1,104 @@
#include <UnicodeChar.h>
#include <Collator.h>
#include <Language.h>
#include <Locale.h>
#include <String.h>
#include <stdio.h>
void
unicode_char_to_string(uint32 c, char *text)
{
BUnicodeChar::ToUTF8(c, &text);
text[0] = '\0';
}
int
main()
{
// Test BUnicodeChar class
char text[16];
for (int32 i = 30; i < 70; i++) {
unicode_char_to_string(i, text);
printf("%s: alpha == %d, alNum == %d, lower == %d, upper == %d, defined == %d, charType == %d\n",
text,
BUnicodeChar::IsAlpha(i), BUnicodeChar::IsAlNum(i), BUnicodeChar::IsLower(i),
BUnicodeChar::IsUpper(i), BUnicodeChar::IsDefined(i), BUnicodeChar::Type(i));
}
uint32 chars[] = {(uint8)'ä', (uint8)'Ö', (uint8)'ß', (uint8)'è', (uint8)'á', (uint8)'é', 0};
for (int32 j = 0, i; (i = chars[j]) != 0; j++) {
unicode_char_to_string(i, text);
printf("%s: alpha == %d, alNum == %d, lower == %d, upper == %d, defined == %d, charType == %d\n",
text,
BUnicodeChar::IsAlpha(i), BUnicodeChar::IsAlNum(i), BUnicodeChar::IsLower(i),
BUnicodeChar::IsUpper(i), BUnicodeChar::IsDefined(i), BUnicodeChar::Type(i));
unicode_char_to_string(BUnicodeChar::ToUpper(i), text);
printf("toUpper == %s, ", text);
unicode_char_to_string(BUnicodeChar::ToLower(i), text);
printf("toLower == %s\n", text);
}
char *utf8chars[] = {"à", "ß", "ñ", "é", "ç", "ä", NULL};
for (int32 j = 0, i; (i = BUnicodeChar::FromUTF8(utf8chars[j])) != 0; j++) {
unicode_char_to_string(i, text);
printf("%s: alpha == %d, alNum == %d, lower == %d, upper == %d, defined == %d, charType == %d\n",
text,
BUnicodeChar::IsAlpha(i), BUnicodeChar::IsAlNum(i), BUnicodeChar::IsLower(i),
BUnicodeChar::IsUpper(i), BUnicodeChar::IsDefined(i), BUnicodeChar::Type(i));
unicode_char_to_string(BUnicodeChar::ToUpper(i), text);
printf("toUpper == %s, ", text);
unicode_char_to_string(BUnicodeChar::ToLower(i), text);
printf("toLower == %s\n", text);
}
printf("%c: digitValue == %ld\n", '8', BUnicodeChar::DigitValue('8'));
// Test BCollator class
BCollator *collator = be_locale->Collator();
char *strings[] = {"gehen", "géhen", "aus", "äUß", "auss", "äUß", "WO",
"", "SO", "so", "açñ", "acn", NULL};
char *strengths[] = {"primary: ", "secondary:", "tertiary: "};
for (int32 i = 0; strings[i]; i += 2) {
for (int32 strength = B_COLLATE_PRIMARY; strength < 4; strength++) {
BString a, b;
collator->GetSortKey(strings[i], &a, strength);
collator->GetSortKey(strings[i + 1], &b, strength);
printf("%s sort keys: \"%s\" -> \"%s\", \"%s\" -> \"%s\"\n",
strengths[strength-1], strings[i], a.String(), strings[i+1], b.String());
printf("\tcmp = %d (key compare = %d)\n",
collator->Compare(strings[i], strings[i + 1], -1, strength),
strcmp(a.String(), b.String()));
}
putchar('\n');
}
// Tests the BLanguage class
BLanguage *language = be_locale->Language();
printf("Language name = \"%s\", code = \"%s\", family = \"%s\"\n", language->Name(),
language->Code(), language->Family());
printf("\tdirection = %s\n",
language->Direction() == B_LEFT_TO_RIGHT ? "left-to-right" :
language->Direction() == B_RIGHT_TO_LEFT ? "right-to-left" :
"top-to-bottom");
//for (int32 i = 0; i < 200; i++) {
// const char *string = language.GetString(i);
// if (string != NULL)
// printf("%ld: %s\n", i, string);
//}
printf("First month = %s (%s)\n",
language->GetString(B_MON_1),
language->GetString(B_AB_MON_1));
}

View File

@ -0,0 +1,13 @@
SubDir LOCALE_TOP test number_format ;
SEARCH_SOURCE += [ FDirName $(SUBDIR) generic_number_format ] ;
UnitTest NumberFormatTests
: NumberFormatTestAddOn.cpp
# BGenericNumberFormat
GenericNumberFormatTests.cpp
GenericNumberFormatConstructorTest.cpp
: be <unittests>liblocale.so
;

View File

@ -0,0 +1,16 @@
#include <TestSuite.h>
#include <TestSuiteAddon.h>
#include "generic_number_format/GenericNumberFormatTests.h"
// getTestSuite
_EXPORT
BTestSuite*
getTestSuite()
{
BTestSuite *suite = new BTestSuite("NumberFormat");
suite->addTest("BGenericNumberFormat", GenericNumberFormatTestSuite());
return suite;
}

View File

@ -0,0 +1,33 @@
#include <stdio.h>
#include <GenericNumberFormat.h>
#include <TestShell.h>
#include <TestUtils.h>
#include <cppunit/TestAssert.h>
#include <cppunit/TestCaller.h>
#include <cppunit/TestSuite.h>
#include "GenericNumberFormatConstructorTest.h"
using namespace CppUnit;
// Suite
Test *
GenericNumberFormatConstructorTest::Suite()
{
CppUnit::TestSuite *suite = new CppUnit::TestSuite();
typedef CppUnit::TestCaller<GenericNumberFormatConstructorTest> TC;
suite->addTest(new TC("BGenericNumberFormat::Constructor Test1",
&GenericNumberFormatConstructorTest::ConstructorTest1));
return suite;
}
// ConstructorTest1
void GenericNumberFormatConstructorTest::ConstructorTest1()
{
BGenericNumberFormat format;
}

View File

@ -0,0 +1,17 @@
#ifndef _GENERIC_NUMBER_FORMAT_CONSTRUCTOR_TEST_
#define _GENERIC_NUMBER_FORMAT_CONSTRUCTOR_TEST_
#include <cppunit/TestCase.h>
class GenericNumberFormatConstructorTest : public CppUnit::TestCase {
public:
GenericNumberFormatConstructorTest() {}
GenericNumberFormatConstructorTest(string name)
: TestCase(name) {}
void ConstructorTest1();
static Test* Suite();
};
#endif // _GENERIC_NUMBER_FORMAT_CONSTRUCTOR_TEST_

View File

@ -0,0 +1,16 @@
#include <cppunit/TestSuite.h>
#include "GenericNumberFormatTests.h"
#include "GenericNumberFormatConstructorTest.h"
// getTestSuite
CppUnit::Test*
GenericNumberFormatTestSuite()
{
CppUnit::TestSuite *testSuite = new CppUnit::TestSuite();
testSuite->addTest(GenericNumberFormatConstructorTest::Suite());
return testSuite;
}

View File

@ -0,0 +1,10 @@
#ifndef _GENERIC_NUMBER_FORMAT_TESTS_H
#define _GENERIC_NUMBER_FORMAT_TESTS_H
namespace CppUnit {
class Test;
}
CppUnit::Test *GenericNumberFormatTestSuite();
#endif // _GENERIC_NUMBER_FORMAT_TESTS_H

3
src/tools/locale/Jamfile Normal file
View File

@ -0,0 +1,3 @@
SubDir LOCALE_TOP tools ;
SubInclude LOCALE_TOP tools genprops ;

View File

@ -0,0 +1,5 @@
SubDir LOCALE_TOP tools genprops ;
SubDirSysHdrs [ FDirName $(LOCALE_TOP) lib ] ;
Application genprops : genprops.cpp store.cpp utf8.cpp PropertyFile.cpp : be ;

View File

@ -0,0 +1,71 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include "PropertyFile.h"
#include "UnicodeProperties.h"
#include <Path.h>
#include <FindDirectory.h>
status_t
PropertyFile::SetTo(const char *directory, const char *name)
{
BPath path(directory,name);
status_t status = BFile::SetTo(path.Path(), B_WRITE_ONLY | B_CREATE_FILE);
if (status < B_OK)
return status;
static UnicodePropertiesHeader header = {
sizeof(UnicodePropertiesHeader),
B_HOST_IS_BENDIAN,
PROPERTIES_FORMAT,
{ 3, 0, 0 } // version (taken from the ICU data version)
};
return Write(&header, sizeof(header));
}
off_t
PropertyFile::Size()
{
off_t size;
if (GetSize(&size) < B_OK)
return 0;
return size - sizeof(UnicodePropertiesHeader);
}
ssize_t
PropertyFile::WritePadding(size_t length)
{
static uint8 padding[16] = {
0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa,
0xaa, 0xaa, 0xaa, 0xaa
};
ssize_t bytesWritten = (ssize_t)length;
while (length >= 16) {
ssize_t written = Write(padding, 16);
if (written < B_OK)
return written;
length -= 16;
}
if (length > 0) {
ssize_t written = Write(padding, length);
if (written < B_OK)
return written;
}
return bytesWritten;
}

View File

@ -0,0 +1,24 @@
/*
** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#ifndef PROPERTY_FILE_H
#define PROPERTY_FILE_H
#include <File.h>
// This is the write-only version of the PropertyFile class - the library
// contains a read-only version of it
class PropertyFile : public BFile {
public:
status_t SetTo(const char *directory, const char *name);
off_t Size();
ssize_t WritePadding(size_t length);
};
#endif /* PROPERTY_FILE_H */

View File

@ -0,0 +1,821 @@
# CaseFolding-2.txt
#
# Case Folding Properties
#
# This file is a supplement to the UnicodeData file.
# It provides a case folding mapping generated from the Unicode Character Database.
# If all characters are mapped according to this mapping, then
# case differences (according to UnicodeData.txt and SpecialCasing.txt)
# are eliminated.
#
# For information on case folding, see
# UTR #21 Case Mappings, at http://www.unicode.org/unicode/reports/tr21/
#
# These are informative character properties.
#
# Send comments to mark@unicode.org
#
# ================================================================================
# Format
# ================================================================================
# The entries in this file are in the following machine-readable format:
#
# <code>; <status>; <mapping>; # <name>
#
# The status is:
# L (for Lowercase) if the case mapping matches the standard 1-1 lowercase mapping
# E (for exception) if it does not.
#
# The mapping may consist of multiple characters.
# If so, they are separated by spaces.
#
# =================================================================
0041; L; 0061; #LATIN CAPITAL LETTER A
0042; L; 0062; #LATIN CAPITAL LETTER B
0043; L; 0063; #LATIN CAPITAL LETTER C
0044; L; 0064; #LATIN CAPITAL LETTER D
0045; L; 0065; #LATIN CAPITAL LETTER E
0046; L; 0066; #LATIN CAPITAL LETTER F
0047; L; 0067; #LATIN CAPITAL LETTER G
0048; L; 0068; #LATIN CAPITAL LETTER H
0049; L; 0069; #LATIN CAPITAL LETTER I
004A; L; 006A; #LATIN CAPITAL LETTER J
004B; L; 006B; #LATIN CAPITAL LETTER K
004C; L; 006C; #LATIN CAPITAL LETTER L
004D; L; 006D; #LATIN CAPITAL LETTER M
004E; L; 006E; #LATIN CAPITAL LETTER N
004F; L; 006F; #LATIN CAPITAL LETTER O
0050; L; 0070; #LATIN CAPITAL LETTER P
0051; L; 0071; #LATIN CAPITAL LETTER Q
0052; L; 0072; #LATIN CAPITAL LETTER R
0053; L; 0073; #LATIN CAPITAL LETTER S
0054; L; 0074; #LATIN CAPITAL LETTER T
0055; L; 0075; #LATIN CAPITAL LETTER U
0056; L; 0076; #LATIN CAPITAL LETTER V
0057; L; 0077; #LATIN CAPITAL LETTER W
0058; L; 0078; #LATIN CAPITAL LETTER X
0059; L; 0079; #LATIN CAPITAL LETTER Y
005A; L; 007A; #LATIN CAPITAL LETTER Z
00B5; E; 03BC; #MICRO SIGN
00C0; L; 00E0; #LATIN CAPITAL LETTER A WITH GRAVE
00C1; L; 00E1; #LATIN CAPITAL LETTER A WITH ACUTE
00C2; L; 00E2; #LATIN CAPITAL LETTER A WITH CIRCUMFLEX
00C3; L; 00E3; #LATIN CAPITAL LETTER A WITH TILDE
00C4; L; 00E4; #LATIN CAPITAL LETTER A WITH DIAERESIS
00C5; L; 00E5; #LATIN CAPITAL LETTER A WITH RING ABOVE
00C6; L; 00E6; #LATIN CAPITAL LETTER AE
00C7; L; 00E7; #LATIN CAPITAL LETTER C WITH CEDILLA
00C8; L; 00E8; #LATIN CAPITAL LETTER E WITH GRAVE
00C9; L; 00E9; #LATIN CAPITAL LETTER E WITH ACUTE
00CA; L; 00EA; #LATIN CAPITAL LETTER E WITH CIRCUMFLEX
00CB; L; 00EB; #LATIN CAPITAL LETTER E WITH DIAERESIS
00CC; L; 00EC; #LATIN CAPITAL LETTER I WITH GRAVE
00CD; L; 00ED; #LATIN CAPITAL LETTER I WITH ACUTE
00CE; L; 00EE; #LATIN CAPITAL LETTER I WITH CIRCUMFLEX
00CF; L; 00EF; #LATIN CAPITAL LETTER I WITH DIAERESIS
00D0; L; 00F0; #LATIN CAPITAL LETTER ETH
00D1; L; 00F1; #LATIN CAPITAL LETTER N WITH TILDE
00D2; L; 00F2; #LATIN CAPITAL LETTER O WITH GRAVE
00D3; L; 00F3; #LATIN CAPITAL LETTER O WITH ACUTE
00D4; L; 00F4; #LATIN CAPITAL LETTER O WITH CIRCUMFLEX
00D5; L; 00F5; #LATIN CAPITAL LETTER O WITH TILDE
00D6; L; 00F6; #LATIN CAPITAL LETTER O WITH DIAERESIS
00D8; L; 00F8; #LATIN CAPITAL LETTER O WITH STROKE
00D9; L; 00F9; #LATIN CAPITAL LETTER U WITH GRAVE
00DA; L; 00FA; #LATIN CAPITAL LETTER U WITH ACUTE
00DB; L; 00FB; #LATIN CAPITAL LETTER U WITH CIRCUMFLEX
00DC; L; 00FC; #LATIN CAPITAL LETTER U WITH DIAERESIS
00DD; L; 00FD; #LATIN CAPITAL LETTER Y WITH ACUTE
00DE; L; 00FE; #LATIN CAPITAL LETTER THORN
00DF; E; 0073 0073; #LATIN SMALL LETTER SHARP S
0100; L; 0101; #LATIN CAPITAL LETTER A WITH MACRON
0102; L; 0103; #LATIN CAPITAL LETTER A WITH BREVE
0104; L; 0105; #LATIN CAPITAL LETTER A WITH OGONEK
0106; L; 0107; #LATIN CAPITAL LETTER C WITH ACUTE
0108; L; 0109; #LATIN CAPITAL LETTER C WITH CIRCUMFLEX
010A; L; 010B; #LATIN CAPITAL LETTER C WITH DOT ABOVE
010C; L; 010D; #LATIN CAPITAL LETTER C WITH CARON
010E; L; 010F; #LATIN CAPITAL LETTER D WITH CARON
0110; L; 0111; #LATIN CAPITAL LETTER D WITH STROKE
0112; L; 0113; #LATIN CAPITAL LETTER E WITH MACRON
0114; L; 0115; #LATIN CAPITAL LETTER E WITH BREVE
0116; L; 0117; #LATIN CAPITAL LETTER E WITH DOT ABOVE
0118; L; 0119; #LATIN CAPITAL LETTER E WITH OGONEK
011A; L; 011B; #LATIN CAPITAL LETTER E WITH CARON
011C; L; 011D; #LATIN CAPITAL LETTER G WITH CIRCUMFLEX
011E; L; 011F; #LATIN CAPITAL LETTER G WITH BREVE
0120; L; 0121; #LATIN CAPITAL LETTER G WITH DOT ABOVE
0122; L; 0123; #LATIN CAPITAL LETTER G WITH CEDILLA
0124; L; 0125; #LATIN CAPITAL LETTER H WITH CIRCUMFLEX
0126; L; 0127; #LATIN CAPITAL LETTER H WITH STROKE
0128; L; 0129; #LATIN CAPITAL LETTER I WITH TILDE
012A; L; 012B; #LATIN CAPITAL LETTER I WITH MACRON
012C; L; 012D; #LATIN CAPITAL LETTER I WITH BREVE
012E; L; 012F; #LATIN CAPITAL LETTER I WITH OGONEK
0130; L; 0069; #LATIN CAPITAL LETTER I WITH DOT ABOVE
0131; E; 0069; #LATIN SMALL LETTER DOTLESS I
0132; L; 0133; #LATIN CAPITAL LIGATURE IJ
0134; L; 0135; #LATIN CAPITAL LETTER J WITH CIRCUMFLEX
0136; L; 0137; #LATIN CAPITAL LETTER K WITH CEDILLA
0139; L; 013A; #LATIN CAPITAL LETTER L WITH ACUTE
013B; L; 013C; #LATIN CAPITAL LETTER L WITH CEDILLA
013D; L; 013E; #LATIN CAPITAL LETTER L WITH CARON
013F; L; 0140; #LATIN CAPITAL LETTER L WITH MIDDLE DOT
0141; L; 0142; #LATIN CAPITAL LETTER L WITH STROKE
0143; L; 0144; #LATIN CAPITAL LETTER N WITH ACUTE
0145; L; 0146; #LATIN CAPITAL LETTER N WITH CEDILLA
0147; L; 0148; #LATIN CAPITAL LETTER N WITH CARON
0149; E; 02BC 006E; #LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
014A; L; 014B; #LATIN CAPITAL LETTER ENG
014C; L; 014D; #LATIN CAPITAL LETTER O WITH MACRON
014E; L; 014F; #LATIN CAPITAL LETTER O WITH BREVE
0150; L; 0151; #LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
0152; L; 0153; #LATIN CAPITAL LIGATURE OE
0154; L; 0155; #LATIN CAPITAL LETTER R WITH ACUTE
0156; L; 0157; #LATIN CAPITAL LETTER R WITH CEDILLA
0158; L; 0159; #LATIN CAPITAL LETTER R WITH CARON
015A; L; 015B; #LATIN CAPITAL LETTER S WITH ACUTE
015C; L; 015D; #LATIN CAPITAL LETTER S WITH CIRCUMFLEX
015E; L; 015F; #LATIN CAPITAL LETTER S WITH CEDILLA
0160; L; 0161; #LATIN CAPITAL LETTER S WITH CARON
0162; L; 0163; #LATIN CAPITAL LETTER T WITH CEDILLA
0164; L; 0165; #LATIN CAPITAL LETTER T WITH CARON
0166; L; 0167; #LATIN CAPITAL LETTER T WITH STROKE
0168; L; 0169; #LATIN CAPITAL LETTER U WITH TILDE
016A; L; 016B; #LATIN CAPITAL LETTER U WITH MACRON
016C; L; 016D; #LATIN CAPITAL LETTER U WITH BREVE
016E; L; 016F; #LATIN CAPITAL LETTER U WITH RING ABOVE
0170; L; 0171; #LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
0172; L; 0173; #LATIN CAPITAL LETTER U WITH OGONEK
0174; L; 0175; #LATIN CAPITAL LETTER W WITH CIRCUMFLEX
0176; L; 0177; #LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
0178; L; 00FF; #LATIN CAPITAL LETTER Y WITH DIAERESIS
0179; L; 017A; #LATIN CAPITAL LETTER Z WITH ACUTE
017B; L; 017C; #LATIN CAPITAL LETTER Z WITH DOT ABOVE
017D; L; 017E; #LATIN CAPITAL LETTER Z WITH CARON
017F; E; 0073; #LATIN SMALL LETTER LONG S
0181; L; 0253; #LATIN CAPITAL LETTER B WITH HOOK
0182; L; 0183; #LATIN CAPITAL LETTER B WITH TOPBAR
0184; L; 0185; #LATIN CAPITAL LETTER TONE SIX
0186; L; 0254; #LATIN CAPITAL LETTER OPEN O
0187; L; 0188; #LATIN CAPITAL LETTER C WITH HOOK
0189; L; 0256; #LATIN CAPITAL LETTER AFRICAN D
018A; L; 0257; #LATIN CAPITAL LETTER D WITH HOOK
018B; L; 018C; #LATIN CAPITAL LETTER D WITH TOPBAR
018E; L; 01DD; #LATIN CAPITAL LETTER REVERSED E
018F; L; 0259; #LATIN CAPITAL LETTER SCHWA
0190; L; 025B; #LATIN CAPITAL LETTER OPEN E
0191; L; 0192; #LATIN CAPITAL LETTER F WITH HOOK
0193; L; 0260; #LATIN CAPITAL LETTER G WITH HOOK
0194; L; 0263; #LATIN CAPITAL LETTER GAMMA
0196; L; 0269; #LATIN CAPITAL LETTER IOTA
0197; L; 0268; #LATIN CAPITAL LETTER I WITH STROKE
0198; L; 0199; #LATIN CAPITAL LETTER K WITH HOOK
019C; L; 026F; #LATIN CAPITAL LETTER TURNED M
019D; L; 0272; #LATIN CAPITAL LETTER N WITH LEFT HOOK
019F; L; 0275; #LATIN CAPITAL LETTER O WITH MIDDLE TILDE
01A0; L; 01A1; #LATIN CAPITAL LETTER O WITH HORN
01A2; L; 01A3; #LATIN CAPITAL LETTER OI
01A4; L; 01A5; #LATIN CAPITAL LETTER P WITH HOOK
01A6; L; 0280; #LATIN LETTER YR
01A7; L; 01A8; #LATIN CAPITAL LETTER TONE TWO
01A9; L; 0283; #LATIN CAPITAL LETTER ESH
01AC; L; 01AD; #LATIN CAPITAL LETTER T WITH HOOK
01AE; L; 0288; #LATIN CAPITAL LETTER T WITH RETROFLEX HOOK
01AF; L; 01B0; #LATIN CAPITAL LETTER U WITH HORN
01B1; L; 028A; #LATIN CAPITAL LETTER UPSILON
01B2; L; 028B; #LATIN CAPITAL LETTER V WITH HOOK
01B3; L; 01B4; #LATIN CAPITAL LETTER Y WITH HOOK
01B5; L; 01B6; #LATIN CAPITAL LETTER Z WITH STROKE
01B7; L; 0292; #LATIN CAPITAL LETTER EZH
01B8; L; 01B9; #LATIN CAPITAL LETTER EZH REVERSED
01BC; L; 01BD; #LATIN CAPITAL LETTER TONE FIVE
01C4; L; 01C6; #LATIN CAPITAL LETTER DZ WITH CARON
01C5; L; 01C6; #LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON
01C7; L; 01C9; #LATIN CAPITAL LETTER LJ
01C8; L; 01C9; #LATIN CAPITAL LETTER L WITH SMALL LETTER J
01CA; L; 01CC; #LATIN CAPITAL LETTER NJ
01CB; L; 01CC; #LATIN CAPITAL LETTER N WITH SMALL LETTER J
01CD; L; 01CE; #LATIN CAPITAL LETTER A WITH CARON
01CF; L; 01D0; #LATIN CAPITAL LETTER I WITH CARON
01D1; L; 01D2; #LATIN CAPITAL LETTER O WITH CARON
01D3; L; 01D4; #LATIN CAPITAL LETTER U WITH CARON
01D5; L; 01D6; #LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
01D7; L; 01D8; #LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
01D9; L; 01DA; #LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
01DB; L; 01DC; #LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
01DE; L; 01DF; #LATIN CAPITAL LETTER A WITH DIAERESIS AND MACRON
01E0; L; 01E1; #LATIN CAPITAL LETTER A WITH DOT ABOVE AND MACRON
01E2; L; 01E3; #LATIN CAPITAL LETTER AE WITH MACRON
01E4; L; 01E5; #LATIN CAPITAL LETTER G WITH STROKE
01E6; L; 01E7; #LATIN CAPITAL LETTER G WITH CARON
01E8; L; 01E9; #LATIN CAPITAL LETTER K WITH CARON
01EA; L; 01EB; #LATIN CAPITAL LETTER O WITH OGONEK
01EC; L; 01ED; #LATIN CAPITAL LETTER O WITH OGONEK AND MACRON
01EE; L; 01EF; #LATIN CAPITAL LETTER EZH WITH CARON
01F0; E; 006A 030C; #LATIN SMALL LETTER J WITH CARON
01F1; L; 01F3; #LATIN CAPITAL LETTER DZ
01F2; L; 01F3; #LATIN CAPITAL LETTER D WITH SMALL LETTER Z
01F4; L; 01F5; #LATIN CAPITAL LETTER G WITH ACUTE
01F6; L; 0195; #LATIN CAPITAL LETTER HWAIR
01F7; L; 01BF; #LATIN CAPITAL LETTER WYNN
01F8; L; 01F9; #LATIN CAPITAL LETTER N WITH GRAVE
01FA; L; 01FB; #LATIN CAPITAL LETTER A WITH RING ABOVE AND ACUTE
01FC; L; 01FD; #LATIN CAPITAL LETTER AE WITH ACUTE
01FE; L; 01FF; #LATIN CAPITAL LETTER O WITH STROKE AND ACUTE
0200; L; 0201; #LATIN CAPITAL LETTER A WITH DOUBLE GRAVE
0202; L; 0203; #LATIN CAPITAL LETTER A WITH INVERTED BREVE
0204; L; 0205; #LATIN CAPITAL LETTER E WITH DOUBLE GRAVE
0206; L; 0207; #LATIN CAPITAL LETTER E WITH INVERTED BREVE
0208; L; 0209; #LATIN CAPITAL LETTER I WITH DOUBLE GRAVE
020A; L; 020B; #LATIN CAPITAL LETTER I WITH INVERTED BREVE
020C; L; 020D; #LATIN CAPITAL LETTER O WITH DOUBLE GRAVE
020E; L; 020F; #LATIN CAPITAL LETTER O WITH INVERTED BREVE
0210; L; 0211; #LATIN CAPITAL LETTER R WITH DOUBLE GRAVE
0212; L; 0213; #LATIN CAPITAL LETTER R WITH INVERTED BREVE
0214; L; 0215; #LATIN CAPITAL LETTER U WITH DOUBLE GRAVE
0216; L; 0217; #LATIN CAPITAL LETTER U WITH INVERTED BREVE
0218; L; 0219; #LATIN CAPITAL LETTER S WITH COMMA BELOW
021A; L; 021B; #LATIN CAPITAL LETTER T WITH COMMA BELOW
021C; L; 021D; #LATIN CAPITAL LETTER YOGH
021E; L; 021F; #LATIN CAPITAL LETTER H WITH CARON
0222; L; 0223; #LATIN CAPITAL LETTER OU
0224; L; 0225; #LATIN CAPITAL LETTER Z WITH HOOK
0226; L; 0227; #LATIN CAPITAL LETTER A WITH DOT ABOVE
0228; L; 0229; #LATIN CAPITAL LETTER E WITH CEDILLA
022A; L; 022B; #LATIN CAPITAL LETTER O WITH DIAERESIS AND MACRON
022C; L; 022D; #LATIN CAPITAL LETTER O WITH TILDE AND MACRON
022E; L; 022F; #LATIN CAPITAL LETTER O WITH DOT ABOVE
0230; L; 0231; #LATIN CAPITAL LETTER O WITH DOT ABOVE AND MACRON
0232; L; 0233; #LATIN CAPITAL LETTER Y WITH MACRON
0345; E; 03B9; #COMBINING GREEK YPOGEGRAMMENI
0386; L; 03AC; #GREEK CAPITAL LETTER ALPHA WITH TONOS
0388; L; 03AD; #GREEK CAPITAL LETTER EPSILON WITH TONOS
0389; L; 03AE; #GREEK CAPITAL LETTER ETA WITH TONOS
038A; L; 03AF; #GREEK CAPITAL LETTER IOTA WITH TONOS
038C; L; 03CC; #GREEK CAPITAL LETTER OMICRON WITH TONOS
038E; L; 03CD; #GREEK CAPITAL LETTER UPSILON WITH TONOS
038F; L; 03CE; #GREEK CAPITAL LETTER OMEGA WITH TONOS
0390; E; 03B9 0308 0301; #GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
0391; L; 03B1; #GREEK CAPITAL LETTER ALPHA
0392; L; 03B2; #GREEK CAPITAL LETTER BETA
0393; L; 03B3; #GREEK CAPITAL LETTER GAMMA
0394; L; 03B4; #GREEK CAPITAL LETTER DELTA
0395; L; 03B5; #GREEK CAPITAL LETTER EPSILON
0396; L; 03B6; #GREEK CAPITAL LETTER ZETA
0397; L; 03B7; #GREEK CAPITAL LETTER ETA
0398; L; 03B8; #GREEK CAPITAL LETTER THETA
0399; L; 03B9; #GREEK CAPITAL LETTER IOTA
039A; L; 03BA; #GREEK CAPITAL LETTER KAPPA
039B; L; 03BB; #GREEK CAPITAL LETTER LAMDA
039C; L; 03BC; #GREEK CAPITAL LETTER MU
039D; L; 03BD; #GREEK CAPITAL LETTER NU
039E; L; 03BE; #GREEK CAPITAL LETTER XI
039F; L; 03BF; #GREEK CAPITAL LETTER OMICRON
03A0; L; 03C0; #GREEK CAPITAL LETTER PI
03A1; L; 03C1; #GREEK CAPITAL LETTER RHO
03A3; E; 03C2; #GREEK CAPITAL LETTER SIGMA
03A4; L; 03C4; #GREEK CAPITAL LETTER TAU
03A5; L; 03C5; #GREEK CAPITAL LETTER UPSILON
03A6; L; 03C6; #GREEK CAPITAL LETTER PHI
03A7; L; 03C7; #GREEK CAPITAL LETTER CHI
03A8; L; 03C8; #GREEK CAPITAL LETTER PSI
03A9; L; 03C9; #GREEK CAPITAL LETTER OMEGA
03AA; L; 03CA; #GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
03AB; L; 03CB; #GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
03B0; E; 03C5 0308 0301; #GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
03C2; L; 03C2; #GREEK SMALL LETTER FINAL SIGMA
03C3; E; 03C2; #GREEK SMALL LETTER SIGMA
03D0; E; 03B2; #GREEK BETA SYMBOL
03D1; E; 03B8; #GREEK THETA SYMBOL
03D5; E; 03C6; #GREEK PHI SYMBOL
03D6; E; 03C0; #GREEK PI SYMBOL
03DA; L; 03DB; #GREEK LETTER STIGMA
03DC; L; 03DD; #GREEK LETTER DIGAMMA
03DE; L; 03DF; #GREEK LETTER KOPPA
03E0; L; 03E1; #GREEK LETTER SAMPI
03E2; L; 03E3; #COPTIC CAPITAL LETTER SHEI
03E4; L; 03E5; #COPTIC CAPITAL LETTER FEI
03E6; L; 03E7; #COPTIC CAPITAL LETTER KHEI
03E8; L; 03E9; #COPTIC CAPITAL LETTER HORI
03EA; L; 03EB; #COPTIC CAPITAL LETTER GANGIA
03EC; L; 03ED; #COPTIC CAPITAL LETTER SHIMA
03EE; L; 03EF; #COPTIC CAPITAL LETTER DEI
03F0; E; 03BA; #GREEK KAPPA SYMBOL
03F1; E; 03C1; #GREEK RHO SYMBOL
03F2; E; 03C2; #GREEK LUNATE SIGMA SYMBOL
0400; L; 0450; #CYRILLIC CAPITAL LETTER IE WITH GRAVE
0401; L; 0451; #CYRILLIC CAPITAL LETTER IO
0402; L; 0452; #CYRILLIC CAPITAL LETTER DJE
0403; L; 0453; #CYRILLIC CAPITAL LETTER GJE
0404; L; 0454; #CYRILLIC CAPITAL LETTER UKRAINIAN IE
0405; L; 0455; #CYRILLIC CAPITAL LETTER DZE
0406; L; 0456; #CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
0407; L; 0457; #CYRILLIC CAPITAL LETTER YI
0408; L; 0458; #CYRILLIC CAPITAL LETTER JE
0409; L; 0459; #CYRILLIC CAPITAL LETTER LJE
040A; L; 045A; #CYRILLIC CAPITAL LETTER NJE
040B; L; 045B; #CYRILLIC CAPITAL LETTER TSHE
040C; L; 045C; #CYRILLIC CAPITAL LETTER KJE
040D; L; 045D; #CYRILLIC CAPITAL LETTER I WITH GRAVE
040E; L; 045E; #CYRILLIC CAPITAL LETTER SHORT U
040F; L; 045F; #CYRILLIC CAPITAL LETTER DZHE
0410; L; 0430; #CYRILLIC CAPITAL LETTER A
0411; L; 0431; #CYRILLIC CAPITAL LETTER BE
0412; L; 0432; #CYRILLIC CAPITAL LETTER VE
0413; L; 0433; #CYRILLIC CAPITAL LETTER GHE
0414; L; 0434; #CYRILLIC CAPITAL LETTER DE
0415; L; 0435; #CYRILLIC CAPITAL LETTER IE
0416; L; 0436; #CYRILLIC CAPITAL LETTER ZHE
0417; L; 0437; #CYRILLIC CAPITAL LETTER ZE
0418; L; 0438; #CYRILLIC CAPITAL LETTER I
0419; L; 0439; #CYRILLIC CAPITAL LETTER SHORT I
041A; L; 043A; #CYRILLIC CAPITAL LETTER KA
041B; L; 043B; #CYRILLIC CAPITAL LETTER EL
041C; L; 043C; #CYRILLIC CAPITAL LETTER EM
041D; L; 043D; #CYRILLIC CAPITAL LETTER EN
041E; L; 043E; #CYRILLIC CAPITAL LETTER O
041F; L; 043F; #CYRILLIC CAPITAL LETTER PE
0420; L; 0440; #CYRILLIC CAPITAL LETTER ER
0421; L; 0441; #CYRILLIC CAPITAL LETTER ES
0422; L; 0442; #CYRILLIC CAPITAL LETTER TE
0423; L; 0443; #CYRILLIC CAPITAL LETTER U
0424; L; 0444; #CYRILLIC CAPITAL LETTER EF
0425; L; 0445; #CYRILLIC CAPITAL LETTER HA
0426; L; 0446; #CYRILLIC CAPITAL LETTER TSE
0427; L; 0447; #CYRILLIC CAPITAL LETTER CHE
0428; L; 0448; #CYRILLIC CAPITAL LETTER SHA
0429; L; 0449; #CYRILLIC CAPITAL LETTER SHCHA
042A; L; 044A; #CYRILLIC CAPITAL LETTER HARD SIGN
042B; L; 044B; #CYRILLIC CAPITAL LETTER YERU
042C; L; 044C; #CYRILLIC CAPITAL LETTER SOFT SIGN
042D; L; 044D; #CYRILLIC CAPITAL LETTER E
042E; L; 044E; #CYRILLIC CAPITAL LETTER YU
042F; L; 044F; #CYRILLIC CAPITAL LETTER YA
0460; L; 0461; #CYRILLIC CAPITAL LETTER OMEGA
0462; L; 0463; #CYRILLIC CAPITAL LETTER YAT
0464; L; 0465; #CYRILLIC CAPITAL LETTER IOTIFIED E
0466; L; 0467; #CYRILLIC CAPITAL LETTER LITTLE YUS
0468; L; 0469; #CYRILLIC CAPITAL LETTER IOTIFIED LITTLE YUS
046A; L; 046B; #CYRILLIC CAPITAL LETTER BIG YUS
046C; L; 046D; #CYRILLIC CAPITAL LETTER IOTIFIED BIG YUS
046E; L; 046F; #CYRILLIC CAPITAL LETTER KSI
0470; L; 0471; #CYRILLIC CAPITAL LETTER PSI
0472; L; 0473; #CYRILLIC CAPITAL LETTER FITA
0474; L; 0475; #CYRILLIC CAPITAL LETTER IZHITSA
0476; L; 0477; #CYRILLIC CAPITAL LETTER IZHITSA WITH DOUBLE GRAVE ACCENT
0478; L; 0479; #CYRILLIC CAPITAL LETTER UK
047A; L; 047B; #CYRILLIC CAPITAL LETTER ROUND OMEGA
047C; L; 047D; #CYRILLIC CAPITAL LETTER OMEGA WITH TITLO
047E; L; 047F; #CYRILLIC CAPITAL LETTER OT
0480; L; 0481; #CYRILLIC CAPITAL LETTER KOPPA
048C; L; 048D; #CYRILLIC CAPITAL LETTER SEMISOFT SIGN
048E; L; 048F; #CYRILLIC CAPITAL LETTER ER WITH TICK
0490; L; 0491; #CYRILLIC CAPITAL LETTER GHE WITH UPTURN
0492; L; 0493; #CYRILLIC CAPITAL LETTER GHE WITH STROKE
0494; L; 0495; #CYRILLIC CAPITAL LETTER GHE WITH MIDDLE HOOK
0496; L; 0497; #CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER
0498; L; 0499; #CYRILLIC CAPITAL LETTER ZE WITH DESCENDER
049A; L; 049B; #CYRILLIC CAPITAL LETTER KA WITH DESCENDER
049C; L; 049D; #CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE
049E; L; 049F; #CYRILLIC CAPITAL LETTER KA WITH STROKE
04A0; L; 04A1; #CYRILLIC CAPITAL LETTER BASHKIR KA
04A2; L; 04A3; #CYRILLIC CAPITAL LETTER EN WITH DESCENDER
04A4; L; 04A5; #CYRILLIC CAPITAL LIGATURE EN GHE
04A6; L; 04A7; #CYRILLIC CAPITAL LETTER PE WITH MIDDLE HOOK
04A8; L; 04A9; #CYRILLIC CAPITAL LETTER ABKHASIAN HA
04AA; L; 04AB; #CYRILLIC CAPITAL LETTER ES WITH DESCENDER
04AC; L; 04AD; #CYRILLIC CAPITAL LETTER TE WITH DESCENDER
04AE; L; 04AF; #CYRILLIC CAPITAL LETTER STRAIGHT U
04B0; L; 04B1; #CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE
04B2; L; 04B3; #CYRILLIC CAPITAL LETTER HA WITH DESCENDER
04B4; L; 04B5; #CYRILLIC CAPITAL LIGATURE TE TSE
04B6; L; 04B7; #CYRILLIC CAPITAL LETTER CHE WITH DESCENDER
04B8; L; 04B9; #CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE
04BA; L; 04BB; #CYRILLIC CAPITAL LETTER SHHA
04BC; L; 04BD; #CYRILLIC CAPITAL LETTER ABKHASIAN CHE
04BE; L; 04BF; #CYRILLIC CAPITAL LETTER ABKHASIAN CHE WITH DESCENDER
04C1; L; 04C2; #CYRILLIC CAPITAL LETTER ZHE WITH BREVE
04C3; L; 04C4; #CYRILLIC CAPITAL LETTER KA WITH HOOK
04C7; L; 04C8; #CYRILLIC CAPITAL LETTER EN WITH HOOK
04CB; L; 04CC; #CYRILLIC CAPITAL LETTER KHAKASSIAN CHE
04D0; L; 04D1; #CYRILLIC CAPITAL LETTER A WITH BREVE
04D2; L; 04D3; #CYRILLIC CAPITAL LETTER A WITH DIAERESIS
04D4; L; 04D5; #CYRILLIC CAPITAL LIGATURE A IE
04D6; L; 04D7; #CYRILLIC CAPITAL LETTER IE WITH BREVE
04D8; L; 04D9; #CYRILLIC CAPITAL LETTER SCHWA
04DA; L; 04DB; #CYRILLIC CAPITAL LETTER SCHWA WITH DIAERESIS
04DC; L; 04DD; #CYRILLIC CAPITAL LETTER ZHE WITH DIAERESIS
04DE; L; 04DF; #CYRILLIC CAPITAL LETTER ZE WITH DIAERESIS
04E0; L; 04E1; #CYRILLIC CAPITAL LETTER ABKHASIAN DZE
04E2; L; 04E3; #CYRILLIC CAPITAL LETTER I WITH MACRON
04E4; L; 04E5; #CYRILLIC CAPITAL LETTER I WITH DIAERESIS
04E6; L; 04E7; #CYRILLIC CAPITAL LETTER O WITH DIAERESIS
04E8; L; 04E9; #CYRILLIC CAPITAL LETTER BARRED O
04EA; L; 04EB; #CYRILLIC CAPITAL LETTER BARRED O WITH DIAERESIS
04EC; L; 04ED; #CYRILLIC CAPITAL LETTER E WITH DIAERESIS
04EE; L; 04EF; #CYRILLIC CAPITAL LETTER U WITH MACRON
04F0; L; 04F1; #CYRILLIC CAPITAL LETTER U WITH DIAERESIS
04F2; L; 04F3; #CYRILLIC CAPITAL LETTER U WITH DOUBLE ACUTE
04F4; L; 04F5; #CYRILLIC CAPITAL LETTER CHE WITH DIAERESIS
04F8; L; 04F9; #CYRILLIC CAPITAL LETTER YERU WITH DIAERESIS
0531; L; 0561; #ARMENIAN CAPITAL LETTER AYB
0532; L; 0562; #ARMENIAN CAPITAL LETTER BEN
0533; L; 0563; #ARMENIAN CAPITAL LETTER GIM
0534; L; 0564; #ARMENIAN CAPITAL LETTER DA
0535; L; 0565; #ARMENIAN CAPITAL LETTER ECH
0536; L; 0566; #ARMENIAN CAPITAL LETTER ZA
0537; L; 0567; #ARMENIAN CAPITAL LETTER EH
0538; L; 0568; #ARMENIAN CAPITAL LETTER ET
0539; L; 0569; #ARMENIAN CAPITAL LETTER TO
053A; L; 056A; #ARMENIAN CAPITAL LETTER ZHE
053B; L; 056B; #ARMENIAN CAPITAL LETTER INI
053C; L; 056C; #ARMENIAN CAPITAL LETTER LIWN
053D; L; 056D; #ARMENIAN CAPITAL LETTER XEH
053E; L; 056E; #ARMENIAN CAPITAL LETTER CA
053F; L; 056F; #ARMENIAN CAPITAL LETTER KEN
0540; L; 0570; #ARMENIAN CAPITAL LETTER HO
0541; L; 0571; #ARMENIAN CAPITAL LETTER JA
0542; L; 0572; #ARMENIAN CAPITAL LETTER GHAD
0543; L; 0573; #ARMENIAN CAPITAL LETTER CHEH
0544; L; 0574; #ARMENIAN CAPITAL LETTER MEN
0545; L; 0575; #ARMENIAN CAPITAL LETTER YI
0546; L; 0576; #ARMENIAN CAPITAL LETTER NOW
0547; L; 0577; #ARMENIAN CAPITAL LETTER SHA
0548; L; 0578; #ARMENIAN CAPITAL LETTER VO
0549; L; 0579; #ARMENIAN CAPITAL LETTER CHA
054A; L; 057A; #ARMENIAN CAPITAL LETTER PEH
054B; L; 057B; #ARMENIAN CAPITAL LETTER JHEH
054C; L; 057C; #ARMENIAN CAPITAL LETTER RA
054D; L; 057D; #ARMENIAN CAPITAL LETTER SEH
054E; L; 057E; #ARMENIAN CAPITAL LETTER VEW
054F; L; 057F; #ARMENIAN CAPITAL LETTER TIWN
0550; L; 0580; #ARMENIAN CAPITAL LETTER REH
0551; L; 0581; #ARMENIAN CAPITAL LETTER CO
0552; L; 0582; #ARMENIAN CAPITAL LETTER YIWN
0553; L; 0583; #ARMENIAN CAPITAL LETTER PIWR
0554; L; 0584; #ARMENIAN CAPITAL LETTER KEH
0555; L; 0585; #ARMENIAN CAPITAL LETTER OH
0556; L; 0586; #ARMENIAN CAPITAL LETTER FEH
0587; E; 0565 0582; #ARMENIAN SMALL LIGATURE ECH YIWN
1E00; L; 1E01; #LATIN CAPITAL LETTER A WITH RING BELOW
1E02; L; 1E03; #LATIN CAPITAL LETTER B WITH DOT ABOVE
1E04; L; 1E05; #LATIN CAPITAL LETTER B WITH DOT BELOW
1E06; L; 1E07; #LATIN CAPITAL LETTER B WITH LINE BELOW
1E08; L; 1E09; #LATIN CAPITAL LETTER C WITH CEDILLA AND ACUTE
1E0A; L; 1E0B; #LATIN CAPITAL LETTER D WITH DOT ABOVE
1E0C; L; 1E0D; #LATIN CAPITAL LETTER D WITH DOT BELOW
1E0E; L; 1E0F; #LATIN CAPITAL LETTER D WITH LINE BELOW
1E10; L; 1E11; #LATIN CAPITAL LETTER D WITH CEDILLA
1E12; L; 1E13; #LATIN CAPITAL LETTER D WITH CIRCUMFLEX BELOW
1E14; L; 1E15; #LATIN CAPITAL LETTER E WITH MACRON AND GRAVE
1E16; L; 1E17; #LATIN CAPITAL LETTER E WITH MACRON AND ACUTE
1E18; L; 1E19; #LATIN CAPITAL LETTER E WITH CIRCUMFLEX BELOW
1E1A; L; 1E1B; #LATIN CAPITAL LETTER E WITH TILDE BELOW
1E1C; L; 1E1D; #LATIN CAPITAL LETTER E WITH CEDILLA AND BREVE
1E1E; L; 1E1F; #LATIN CAPITAL LETTER F WITH DOT ABOVE
1E20; L; 1E21; #LATIN CAPITAL LETTER G WITH MACRON
1E22; L; 1E23; #LATIN CAPITAL LETTER H WITH DOT ABOVE
1E24; L; 1E25; #LATIN CAPITAL LETTER H WITH DOT BELOW
1E26; L; 1E27; #LATIN CAPITAL LETTER H WITH DIAERESIS
1E28; L; 1E29; #LATIN CAPITAL LETTER H WITH CEDILLA
1E2A; L; 1E2B; #LATIN CAPITAL LETTER H WITH BREVE BELOW
1E2C; L; 1E2D; #LATIN CAPITAL LETTER I WITH TILDE BELOW
1E2E; L; 1E2F; #LATIN CAPITAL LETTER I WITH DIAERESIS AND ACUTE
1E30; L; 1E31; #LATIN CAPITAL LETTER K WITH ACUTE
1E32; L; 1E33; #LATIN CAPITAL LETTER K WITH DOT BELOW
1E34; L; 1E35; #LATIN CAPITAL LETTER K WITH LINE BELOW
1E36; L; 1E37; #LATIN CAPITAL LETTER L WITH DOT BELOW
1E38; L; 1E39; #LATIN CAPITAL LETTER L WITH DOT BELOW AND MACRON
1E3A; L; 1E3B; #LATIN CAPITAL LETTER L WITH LINE BELOW
1E3C; L; 1E3D; #LATIN CAPITAL LETTER L WITH CIRCUMFLEX BELOW
1E3E; L; 1E3F; #LATIN CAPITAL LETTER M WITH ACUTE
1E40; L; 1E41; #LATIN CAPITAL LETTER M WITH DOT ABOVE
1E42; L; 1E43; #LATIN CAPITAL LETTER M WITH DOT BELOW
1E44; L; 1E45; #LATIN CAPITAL LETTER N WITH DOT ABOVE
1E46; L; 1E47; #LATIN CAPITAL LETTER N WITH DOT BELOW
1E48; L; 1E49; #LATIN CAPITAL LETTER N WITH LINE BELOW
1E4A; L; 1E4B; #LATIN CAPITAL LETTER N WITH CIRCUMFLEX BELOW
1E4C; L; 1E4D; #LATIN CAPITAL LETTER O WITH TILDE AND ACUTE
1E4E; L; 1E4F; #LATIN CAPITAL LETTER O WITH TILDE AND DIAERESIS
1E50; L; 1E51; #LATIN CAPITAL LETTER O WITH MACRON AND GRAVE
1E52; L; 1E53; #LATIN CAPITAL LETTER O WITH MACRON AND ACUTE
1E54; L; 1E55; #LATIN CAPITAL LETTER P WITH ACUTE
1E56; L; 1E57; #LATIN CAPITAL LETTER P WITH DOT ABOVE
1E58; L; 1E59; #LATIN CAPITAL LETTER R WITH DOT ABOVE
1E5A; L; 1E5B; #LATIN CAPITAL LETTER R WITH DOT BELOW
1E5C; L; 1E5D; #LATIN CAPITAL LETTER R WITH DOT BELOW AND MACRON
1E5E; L; 1E5F; #LATIN CAPITAL LETTER R WITH LINE BELOW
1E60; L; 1E61; #LATIN CAPITAL LETTER S WITH DOT ABOVE
1E62; L; 1E63; #LATIN CAPITAL LETTER S WITH DOT BELOW
1E64; L; 1E65; #LATIN CAPITAL LETTER S WITH ACUTE AND DOT ABOVE
1E66; L; 1E67; #LATIN CAPITAL LETTER S WITH CARON AND DOT ABOVE
1E68; L; 1E69; #LATIN CAPITAL LETTER S WITH DOT BELOW AND DOT ABOVE
1E6A; L; 1E6B; #LATIN CAPITAL LETTER T WITH DOT ABOVE
1E6C; L; 1E6D; #LATIN CAPITAL LETTER T WITH DOT BELOW
1E6E; L; 1E6F; #LATIN CAPITAL LETTER T WITH LINE BELOW
1E70; L; 1E71; #LATIN CAPITAL LETTER T WITH CIRCUMFLEX BELOW
1E72; L; 1E73; #LATIN CAPITAL LETTER U WITH DIAERESIS BELOW
1E74; L; 1E75; #LATIN CAPITAL LETTER U WITH TILDE BELOW
1E76; L; 1E77; #LATIN CAPITAL LETTER U WITH CIRCUMFLEX BELOW
1E78; L; 1E79; #LATIN CAPITAL LETTER U WITH TILDE AND ACUTE
1E7A; L; 1E7B; #LATIN CAPITAL LETTER U WITH MACRON AND DIAERESIS
1E7C; L; 1E7D; #LATIN CAPITAL LETTER V WITH TILDE
1E7E; L; 1E7F; #LATIN CAPITAL LETTER V WITH DOT BELOW
1E80; L; 1E81; #LATIN CAPITAL LETTER W WITH GRAVE
1E82; L; 1E83; #LATIN CAPITAL LETTER W WITH ACUTE
1E84; L; 1E85; #LATIN CAPITAL LETTER W WITH DIAERESIS
1E86; L; 1E87; #LATIN CAPITAL LETTER W WITH DOT ABOVE
1E88; L; 1E89; #LATIN CAPITAL LETTER W WITH DOT BELOW
1E8A; L; 1E8B; #LATIN CAPITAL LETTER X WITH DOT ABOVE
1E8C; L; 1E8D; #LATIN CAPITAL LETTER X WITH DIAERESIS
1E8E; L; 1E8F; #LATIN CAPITAL LETTER Y WITH DOT ABOVE
1E90; L; 1E91; #LATIN CAPITAL LETTER Z WITH CIRCUMFLEX
1E92; L; 1E93; #LATIN CAPITAL LETTER Z WITH DOT BELOW
1E94; L; 1E95; #LATIN CAPITAL LETTER Z WITH LINE BELOW
1E96; E; 0068 0331; #LATIN SMALL LETTER H WITH LINE BELOW
1E97; E; 0074 0308; #LATIN SMALL LETTER T WITH DIAERESIS
1E98; E; 0077 030A; #LATIN SMALL LETTER W WITH RING ABOVE
1E99; E; 0079 030A; #LATIN SMALL LETTER Y WITH RING ABOVE
1E9A; E; 0061 02BE; #LATIN SMALL LETTER A WITH RIGHT HALF RING
1E9B; E; 1E61; #LATIN SMALL LETTER LONG S WITH DOT ABOVE
1EA0; L; 1EA1; #LATIN CAPITAL LETTER A WITH DOT BELOW
1EA2; L; 1EA3; #LATIN CAPITAL LETTER A WITH HOOK ABOVE
1EA4; L; 1EA5; #LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE
1EA6; L; 1EA7; #LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE
1EA8; L; 1EA9; #LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE
1EAA; L; 1EAB; #LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE
1EAC; L; 1EAD; #LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW
1EAE; L; 1EAF; #LATIN CAPITAL LETTER A WITH BREVE AND ACUTE
1EB0; L; 1EB1; #LATIN CAPITAL LETTER A WITH BREVE AND GRAVE
1EB2; L; 1EB3; #LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE
1EB4; L; 1EB5; #LATIN CAPITAL LETTER A WITH BREVE AND TILDE
1EB6; L; 1EB7; #LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW
1EB8; L; 1EB9; #LATIN CAPITAL LETTER E WITH DOT BELOW
1EBA; L; 1EBB; #LATIN CAPITAL LETTER E WITH HOOK ABOVE
1EBC; L; 1EBD; #LATIN CAPITAL LETTER E WITH TILDE
1EBE; L; 1EBF; #LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE
1EC0; L; 1EC1; #LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE
1EC2; L; 1EC3; #LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE
1EC4; L; 1EC5; #LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE
1EC6; L; 1EC7; #LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW
1EC8; L; 1EC9; #LATIN CAPITAL LETTER I WITH HOOK ABOVE
1ECA; L; 1ECB; #LATIN CAPITAL LETTER I WITH DOT BELOW
1ECC; L; 1ECD; #LATIN CAPITAL LETTER O WITH DOT BELOW
1ECE; L; 1ECF; #LATIN CAPITAL LETTER O WITH HOOK ABOVE
1ED0; L; 1ED1; #LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE
1ED2; L; 1ED3; #LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE
1ED4; L; 1ED5; #LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE
1ED6; L; 1ED7; #LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE
1ED8; L; 1ED9; #LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW
1EDA; L; 1EDB; #LATIN CAPITAL LETTER O WITH HORN AND ACUTE
1EDC; L; 1EDD; #LATIN CAPITAL LETTER O WITH HORN AND GRAVE
1EDE; L; 1EDF; #LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE
1EE0; L; 1EE1; #LATIN CAPITAL LETTER O WITH HORN AND TILDE
1EE2; L; 1EE3; #LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW
1EE4; L; 1EE5; #LATIN CAPITAL LETTER U WITH DOT BELOW
1EE6; L; 1EE7; #LATIN CAPITAL LETTER U WITH HOOK ABOVE
1EE8; L; 1EE9; #LATIN CAPITAL LETTER U WITH HORN AND ACUTE
1EEA; L; 1EEB; #LATIN CAPITAL LETTER U WITH HORN AND GRAVE
1EEC; L; 1EED; #LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE
1EEE; L; 1EEF; #LATIN CAPITAL LETTER U WITH HORN AND TILDE
1EF0; L; 1EF1; #LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW
1EF2; L; 1EF3; #LATIN CAPITAL LETTER Y WITH GRAVE
1EF4; L; 1EF5; #LATIN CAPITAL LETTER Y WITH DOT BELOW
1EF6; L; 1EF7; #LATIN CAPITAL LETTER Y WITH HOOK ABOVE
1EF8; L; 1EF9; #LATIN CAPITAL LETTER Y WITH TILDE
1F08; L; 1F00; #GREEK CAPITAL LETTER ALPHA WITH PSILI
1F09; L; 1F01; #GREEK CAPITAL LETTER ALPHA WITH DASIA
1F0A; L; 1F02; #GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA
1F0B; L; 1F03; #GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA
1F0C; L; 1F04; #GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA
1F0D; L; 1F05; #GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA
1F0E; L; 1F06; #GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI
1F0F; L; 1F07; #GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI
1F18; L; 1F10; #GREEK CAPITAL LETTER EPSILON WITH PSILI
1F19; L; 1F11; #GREEK CAPITAL LETTER EPSILON WITH DASIA
1F1A; L; 1F12; #GREEK CAPITAL LETTER EPSILON WITH PSILI AND VARIA
1F1B; L; 1F13; #GREEK CAPITAL LETTER EPSILON WITH DASIA AND VARIA
1F1C; L; 1F14; #GREEK CAPITAL LETTER EPSILON WITH PSILI AND OXIA
1F1D; L; 1F15; #GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA
1F28; L; 1F20; #GREEK CAPITAL LETTER ETA WITH PSILI
1F29; L; 1F21; #GREEK CAPITAL LETTER ETA WITH DASIA
1F2A; L; 1F22; #GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA
1F2B; L; 1F23; #GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA
1F2C; L; 1F24; #GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA
1F2D; L; 1F25; #GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA
1F2E; L; 1F26; #GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI
1F2F; L; 1F27; #GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI
1F38; L; 1F30; #GREEK CAPITAL LETTER IOTA WITH PSILI
1F39; L; 1F31; #GREEK CAPITAL LETTER IOTA WITH DASIA
1F3A; L; 1F32; #GREEK CAPITAL LETTER IOTA WITH PSILI AND VARIA
1F3B; L; 1F33; #GREEK CAPITAL LETTER IOTA WITH DASIA AND VARIA
1F3C; L; 1F34; #GREEK CAPITAL LETTER IOTA WITH PSILI AND OXIA
1F3D; L; 1F35; #GREEK CAPITAL LETTER IOTA WITH DASIA AND OXIA
1F3E; L; 1F36; #GREEK CAPITAL LETTER IOTA WITH PSILI AND PERISPOMENI
1F3F; L; 1F37; #GREEK CAPITAL LETTER IOTA WITH DASIA AND PERISPOMENI
1F48; L; 1F40; #GREEK CAPITAL LETTER OMICRON WITH PSILI
1F49; L; 1F41; #GREEK CAPITAL LETTER OMICRON WITH DASIA
1F4A; L; 1F42; #GREEK CAPITAL LETTER OMICRON WITH PSILI AND VARIA
1F4B; L; 1F43; #GREEK CAPITAL LETTER OMICRON WITH DASIA AND VARIA
1F4C; L; 1F44; #GREEK CAPITAL LETTER OMICRON WITH PSILI AND OXIA
1F4D; L; 1F45; #GREEK CAPITAL LETTER OMICRON WITH DASIA AND OXIA
1F50; E; 03C5 0313; #GREEK SMALL LETTER UPSILON WITH PSILI
1F52; E; 03C5 0313 0300; #GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
1F54; E; 03C5 0313 0301; #GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
1F56; E; 03C5 0313 0342; #GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
1F59; L; 1F51; #GREEK CAPITAL LETTER UPSILON WITH DASIA
1F5B; L; 1F53; #GREEK CAPITAL LETTER UPSILON WITH DASIA AND VARIA
1F5D; L; 1F55; #GREEK CAPITAL LETTER UPSILON WITH DASIA AND OXIA
1F5F; L; 1F57; #GREEK CAPITAL LETTER UPSILON WITH DASIA AND PERISPOMENI
1F68; L; 1F60; #GREEK CAPITAL LETTER OMEGA WITH PSILI
1F69; L; 1F61; #GREEK CAPITAL LETTER OMEGA WITH DASIA
1F6A; L; 1F62; #GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA
1F6B; L; 1F63; #GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA
1F6C; L; 1F64; #GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA
1F6D; L; 1F65; #GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA
1F6E; L; 1F66; #GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI
1F6F; L; 1F67; #GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI
1F80; E; 1F00 03B9; #GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
1F81; E; 1F01 03B9; #GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
1F82; E; 1F02 03B9; #GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1F83; E; 1F03 03B9; #GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1F84; E; 1F04 03B9; #GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1F85; E; 1F05 03B9; #GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1F86; E; 1F06 03B9; #GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1F87; E; 1F07 03B9; #GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1F88; E; 1F00 03B9; #GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
1F89; E; 1F01 03B9; #GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
1F8A; E; 1F02 03B9; #GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1F8B; E; 1F03 03B9; #GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1F8C; E; 1F04 03B9; #GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1F8D; E; 1F05 03B9; #GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1F8E; E; 1F06 03B9; #GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1F8F; E; 1F07 03B9; #GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1F90; E; 1F20 03B9; #GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
1F91; E; 1F21 03B9; #GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
1F92; E; 1F22 03B9; #GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1F93; E; 1F23 03B9; #GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1F94; E; 1F24 03B9; #GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1F95; E; 1F25 03B9; #GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1F96; E; 1F26 03B9; #GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1F97; E; 1F27 03B9; #GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1F98; E; 1F20 03B9; #GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
1F99; E; 1F21 03B9; #GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
1F9A; E; 1F22 03B9; #GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1F9B; E; 1F23 03B9; #GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1F9C; E; 1F24 03B9; #GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1F9D; E; 1F25 03B9; #GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1F9E; E; 1F26 03B9; #GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1F9F; E; 1F27 03B9; #GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1FA0; E; 1F60 03B9; #GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
1FA1; E; 1F61 03B9; #GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
1FA2; E; 1F62 03B9; #GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1FA3; E; 1F63 03B9; #GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1FA4; E; 1F64 03B9; #GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1FA5; E; 1F65 03B9; #GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1FA6; E; 1F66 03B9; #GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1FA7; E; 1F67 03B9; #GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1FA8; E; 1F60 03B9; #GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
1FA9; E; 1F61 03B9; #GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
1FAA; E; 1F62 03B9; #GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1FAB; E; 1F63 03B9; #GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1FAC; E; 1F64 03B9; #GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1FAD; E; 1F65 03B9; #GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1FAE; E; 1F66 03B9; #GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1FAF; E; 1F67 03B9; #GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1FB2; E; 1F70 03B9; #GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
1FB3; E; 03B1 03B9; #GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
1FB4; E; 03AC 03B9; #GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
1FB6; E; 03B1 0342; #GREEK SMALL LETTER ALPHA WITH PERISPOMENI
1FB7; E; 03B1 0342 03B9; #GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
1FB8; L; 1FB0; #GREEK CAPITAL LETTER ALPHA WITH VRACHY
1FB9; L; 1FB1; #GREEK CAPITAL LETTER ALPHA WITH MACRON
1FBA; L; 1F70; #GREEK CAPITAL LETTER ALPHA WITH VARIA
1FBB; L; 1F71; #GREEK CAPITAL LETTER ALPHA WITH OXIA
1FBC; E; 03B1 03B9; #GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
1FBE; E; 03B9; #GREEK PROSGEGRAMMENI
1FC2; E; 1F74 03B9; #GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
1FC3; E; 03B7 03B9; #GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
1FC4; E; 03AE 03B9; #GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
1FC6; E; 03B7 0342; #GREEK SMALL LETTER ETA WITH PERISPOMENI
1FC7; E; 03B7 0342 03B9; #GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
1FC8; L; 1F72; #GREEK CAPITAL LETTER EPSILON WITH VARIA
1FC9; L; 1F73; #GREEK CAPITAL LETTER EPSILON WITH OXIA
1FCA; L; 1F74; #GREEK CAPITAL LETTER ETA WITH VARIA
1FCB; L; 1F75; #GREEK CAPITAL LETTER ETA WITH OXIA
1FCC; E; 03B7 03B9; #GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
1FD2; E; 03B9 0308 0300; #GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
1FD3; E; 03B9 0308 0301; #GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
1FD6; E; 03B9 0342; #GREEK SMALL LETTER IOTA WITH PERISPOMENI
1FD7; E; 03B9 0308 0342; #GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
1FD8; L; 1FD0; #GREEK CAPITAL LETTER IOTA WITH VRACHY
1FD9; L; 1FD1; #GREEK CAPITAL LETTER IOTA WITH MACRON
1FDA; L; 1F76; #GREEK CAPITAL LETTER IOTA WITH VARIA
1FDB; L; 1F77; #GREEK CAPITAL LETTER IOTA WITH OXIA
1FE2; E; 03C5 0308 0300; #GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
1FE3; E; 03C5 0308 0301; #GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
1FE4; E; 03C1 0313; #GREEK SMALL LETTER RHO WITH PSILI
1FE6; E; 03C5 0342; #GREEK SMALL LETTER UPSILON WITH PERISPOMENI
1FE7; E; 03C5 0308 0342; #GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
1FE8; L; 1FE0; #GREEK CAPITAL LETTER UPSILON WITH VRACHY
1FE9; L; 1FE1; #GREEK CAPITAL LETTER UPSILON WITH MACRON
1FEA; L; 1F7A; #GREEK CAPITAL LETTER UPSILON WITH VARIA
1FEB; L; 1F7B; #GREEK CAPITAL LETTER UPSILON WITH OXIA
1FEC; L; 1FE5; #GREEK CAPITAL LETTER RHO WITH DASIA
1FF2; E; 1F7C 03B9; #GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
1FF3; E; 03C9 03B9; #GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
1FF4; E; 03CE 03B9; #GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
1FF6; E; 03C9 0342; #GREEK SMALL LETTER OMEGA WITH PERISPOMENI
1FF7; E; 03C9 0342 03B9; #GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
1FF8; L; 1F78; #GREEK CAPITAL LETTER OMICRON WITH VARIA
1FF9; L; 1F79; #GREEK CAPITAL LETTER OMICRON WITH OXIA
1FFA; L; 1F7C; #GREEK CAPITAL LETTER OMEGA WITH VARIA
1FFB; L; 1F7D; #GREEK CAPITAL LETTER OMEGA WITH OXIA
1FFC; E; 03C9 03B9; #GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
2126; L; 03C9; #OHM SIGN
212A; L; 006B; #KELVIN SIGN
212B; L; 00E5; #ANGSTROM SIGN
2160; L; 2170; #ROMAN NUMERAL ONE
2161; L; 2171; #ROMAN NUMERAL TWO
2162; L; 2172; #ROMAN NUMERAL THREE
2163; L; 2173; #ROMAN NUMERAL FOUR
2164; L; 2174; #ROMAN NUMERAL FIVE
2165; L; 2175; #ROMAN NUMERAL SIX
2166; L; 2176; #ROMAN NUMERAL SEVEN
2167; L; 2177; #ROMAN NUMERAL EIGHT
2168; L; 2178; #ROMAN NUMERAL NINE
2169; L; 2179; #ROMAN NUMERAL TEN
216A; L; 217A; #ROMAN NUMERAL ELEVEN
216B; L; 217B; #ROMAN NUMERAL TWELVE
216C; L; 217C; #ROMAN NUMERAL FIFTY
216D; L; 217D; #ROMAN NUMERAL ONE HUNDRED
216E; L; 217E; #ROMAN NUMERAL FIVE HUNDRED
216F; L; 217F; #ROMAN NUMERAL ONE THOUSAND
24B6; L; 24D0; #CIRCLED LATIN CAPITAL LETTER A
24B7; L; 24D1; #CIRCLED LATIN CAPITAL LETTER B
24B8; L; 24D2; #CIRCLED LATIN CAPITAL LETTER C
24B9; L; 24D3; #CIRCLED LATIN CAPITAL LETTER D
24BA; L; 24D4; #CIRCLED LATIN CAPITAL LETTER E
24BB; L; 24D5; #CIRCLED LATIN CAPITAL LETTER F
24BC; L; 24D6; #CIRCLED LATIN CAPITAL LETTER G
24BD; L; 24D7; #CIRCLED LATIN CAPITAL LETTER H
24BE; L; 24D8; #CIRCLED LATIN CAPITAL LETTER I
24BF; L; 24D9; #CIRCLED LATIN CAPITAL LETTER J
24C0; L; 24DA; #CIRCLED LATIN CAPITAL LETTER K
24C1; L; 24DB; #CIRCLED LATIN CAPITAL LETTER L
24C2; L; 24DC; #CIRCLED LATIN CAPITAL LETTER M
24C3; L; 24DD; #CIRCLED LATIN CAPITAL LETTER N
24C4; L; 24DE; #CIRCLED LATIN CAPITAL LETTER O
24C5; L; 24DF; #CIRCLED LATIN CAPITAL LETTER P
24C6; L; 24E0; #CIRCLED LATIN CAPITAL LETTER Q
24C7; L; 24E1; #CIRCLED LATIN CAPITAL LETTER R
24C8; L; 24E2; #CIRCLED LATIN CAPITAL LETTER S
24C9; L; 24E3; #CIRCLED LATIN CAPITAL LETTER T
24CA; L; 24E4; #CIRCLED LATIN CAPITAL LETTER U
24CB; L; 24E5; #CIRCLED LATIN CAPITAL LETTER V
24CC; L; 24E6; #CIRCLED LATIN CAPITAL LETTER W
24CD; L; 24E7; #CIRCLED LATIN CAPITAL LETTER X
24CE; L; 24E8; #CIRCLED LATIN CAPITAL LETTER Y
24CF; L; 24E9; #CIRCLED LATIN CAPITAL LETTER Z
FB00; E; 0066 0066; #LATIN SMALL LIGATURE FF
FB01; E; 0066 0069; #LATIN SMALL LIGATURE FI
FB02; E; 0066 006C; #LATIN SMALL LIGATURE FL
FB03; E; 0066 0066 0069; #LATIN SMALL LIGATURE FFI
FB04; E; 0066 0066 006C; #LATIN SMALL LIGATURE FFL
FB05; E; 0073 0074; #LATIN SMALL LIGATURE LONG S T
FB06; E; 0073 0074; #LATIN SMALL LIGATURE ST
FB13; E; 0574 0576; #ARMENIAN SMALL LIGATURE MEN NOW
FB14; E; 0574 0565; #ARMENIAN SMALL LIGATURE MEN ECH
FB15; E; 0574 056B; #ARMENIAN SMALL LIGATURE MEN INI
FB16; E; 057E 0576; #ARMENIAN SMALL LIGATURE VEW NOW
FB17; E; 0574 056D; #ARMENIAN SMALL LIGATURE MEN XEH
FF21; L; FF41; #FULLWIDTH LATIN CAPITAL LETTER A
FF22; L; FF42; #FULLWIDTH LATIN CAPITAL LETTER B
FF23; L; FF43; #FULLWIDTH LATIN CAPITAL LETTER C
FF24; L; FF44; #FULLWIDTH LATIN CAPITAL LETTER D
FF25; L; FF45; #FULLWIDTH LATIN CAPITAL LETTER E
FF26; L; FF46; #FULLWIDTH LATIN CAPITAL LETTER F
FF27; L; FF47; #FULLWIDTH LATIN CAPITAL LETTER G
FF28; L; FF48; #FULLWIDTH LATIN CAPITAL LETTER H
FF29; L; FF49; #FULLWIDTH LATIN CAPITAL LETTER I
FF2A; L; FF4A; #FULLWIDTH LATIN CAPITAL LETTER J
FF2B; L; FF4B; #FULLWIDTH LATIN CAPITAL LETTER K
FF2C; L; FF4C; #FULLWIDTH LATIN CAPITAL LETTER L
FF2D; L; FF4D; #FULLWIDTH LATIN CAPITAL LETTER M
FF2E; L; FF4E; #FULLWIDTH LATIN CAPITAL LETTER N
FF2F; L; FF4F; #FULLWIDTH LATIN CAPITAL LETTER O
FF30; L; FF50; #FULLWIDTH LATIN CAPITAL LETTER P
FF31; L; FF51; #FULLWIDTH LATIN CAPITAL LETTER Q
FF32; L; FF52; #FULLWIDTH LATIN CAPITAL LETTER R
FF33; L; FF53; #FULLWIDTH LATIN CAPITAL LETTER S
FF34; L; FF54; #FULLWIDTH LATIN CAPITAL LETTER T
FF35; L; FF55; #FULLWIDTH LATIN CAPITAL LETTER U
FF36; L; FF56; #FULLWIDTH LATIN CAPITAL LETTER V
FF37; L; FF57; #FULLWIDTH LATIN CAPITAL LETTER W
FF38; L; FF58; #FULLWIDTH LATIN CAPITAL LETTER X
FF39; L; FF59; #FULLWIDTH LATIN CAPITAL LETTER Y
FF3A; L; FF5A; #FULLWIDTH LATIN CAPITAL LETTER Z

View File

@ -0,0 +1,245 @@
# Mirror.txt
# Informative properties for Unicode characters:
# This file lists characters that have the mirrored property
# where there is another Unicode character that typically has a glyph
# that is the mirror image of the original character's glyph.
# The file contains a list of lines with mappings from one code point
# to another one for character-based mirroring.
# Note that for "real" mirroring, a rendering engine needs to select
# appropriate alternative glyphs, and that many Unicode characters do not
# have a mirror-image Unicode character.
# Each mapping line contains two fields, separated by a semicolon (';').
# Each of the two fields contains a code point represented as a
# variable-length hexadecimal value with 1 to 6 digits.
# The mapping lines are listed in ascending order by the first field, the
# original code points.
28;29
29;28
3C;3E
3E;3C
5B;5D
5D;5B
7B;7D
7D;7B
AB;BB
BB;AB
2039;203A
203A;2039
2045;2046
2046;2045
207D;207E
207E;207D
208D;208E
208E;208D
2201;2201
2202;2202
2203;2203
2204;2204
2208;220B
2209;220C
220A;220D
220B;2208
220C;2209
220D;220A
2211;2211
2215;2216
2216;2215
221A;221A
221B;221B
221C;221C
221D;221D
221F;221F
2220;2220
2221;2221
2222;2222
2224;2224
2226;2226
222B;222B
222C;222C
222D;222D
222E;222E
222F;222F
2230;2230
2231;2231
2232;2232
2233;2233
2239;2239
223B;223B
223C;223D
223D;223C
223E;223E
223F;223F
2240;2240
2241;2241
2242;2242
2243;22CD
2244;2244
2245;2245
2246;2246
2247;2247
2248;2248
2249;2249
224A;224A
224B;224B
224C;224C
2252;2253
2253;2252
2254;2255
2255;2254
225F;225F
2260;2260
2262;2262
2264;2265
2265;2264
2266;2267
2267;2266
2268;2269
2269;2268
226A;226B
226B;226A
226E;226F
226F;226E
2270;2271
2271;2270
2272;2273
2273;2272
2274;2275
2275;2274
2276;2277
2277;2276
2278;2279
2279;2278
227A;227B
227B;227A
227C;227D
227D;227C
227E;227F
227F;227E
2280;2281
2281;2280
2282;2283
2283;2282
2284;2285
2285;2284
2286;2287
2287;2286
2288;2289
2289;2288
228A;228B
228B;228A
228C;228C
228F;2290
2290;228F
2291;2292
2292;2291
2298;2298
22A2;22A3
22A3;22A2
22A6;22A6
22A7;22A7
22A8;22A8
22A9;22A9
22AA;22AA
22AB;22AB
22AC;22AC
22AD;22AD
22AE;22AE
22AF;22AF
22B0;22B1
22B1;22B0
22B2;22B3
22B3;22B2
22B4;22B5
22B5;22B4
22B6;22B7
22B7;22B6
22B8;22B8
22BE;22BE
22BF;22BF
22C9;22CA
22CA;22C9
22CB;22CC
22CC;22CB
22CD;2243
22D0;22D1
22D1;22D0
22D6;22D7
22D7;22D6
22D8;22D9
22D9;22D8
22DA;22DB
22DB;22DA
22DC;22DD
22DD;22DC
22DE;22DF
22DF;22DE
22E0;22E1
22E1;22E0
22E2;22E3
22E3;22E2
22E4;22E5
22E5;22E4
22E6;22E7
22E7;22E6
22E8;22E9
22E9;22E8
22EA;22EB
22EB;22EA
22EC;22ED
22ED;22EC
22F0;22F1
22F1;22F0
2308;2309
2309;2308
230A;230B
230B;230A
2320;2320
2321;2321
2329;232A
232A;2329
3008;3009
3009;3008
300A;300B
300B;300A
300C;300C
300D;300D
300E;300E
300F;300F
3010;3011
3011;3010
3014;3014
3015;3015
3016;3017
3017;3016
3018;3019
3019;3018
301A;301B
301B;301A
# Mirrored-character mappings for characters that are missing the mirrored property:
# Not listed are characters that could have the mirrored property but would not
# have a mirror-image mapping.
# Mathematical Operators
# 2205;2349
# APL
# No APL symbol has the mirrored property!
# 2300;2349
# 2326;232B
# 232B;2326
# 233F;2340
# 2340;233F
# 2341;2342
# 2342;2341
# 2343;2344
# 2344;2343
# 2345;2346
# 2346;2345
# 2347;2348
# 2348;2347
# 2349;2205

View File

@ -0,0 +1,219 @@
# SpecialCasing-2.txt
#
# Special Casing Properties
#
# This file is a supplement to the UnicodeData file.
# It contains additional information about the casing of Unicode characters.
# (For compatibility, the UnicodeData.txt file only contains case mappings for
# characters where they are 1-1, and does not have locale-specific mappings.)
# These are informative character properties.
#
# Send comments to mark@unicode.org
#
# ================================================================================
# Format
# ================================================================================
# The entries in this file are in the following machine-readable format:
#
# <entry> := <case_mapping> <condition_list>? (<s>* "#" <comment>)?
#
# <case_mapping> := <source> <sep> <lower> <sep> <title> <sep> <upper> <sep>
#
# <source> := <code_point>
# <sep> := <s>* ";" <s>*
# <lower> := <code_point_list>
# <title> := <code_point_list>
# <upper> := <code_point_list>
# <code_point_list> := <code_point> (<s>+ <code_point>)*
# <code_point> := <hex><hex><hex><hex>
# <hex> := [0-1A-Fa-f]
# <s> := <space>
#
# <condition_list> := <locale>? (<s>+ <context>)*
# <locale> := <ISO_3166_code> ( "_" <ISO_639_code> )? ( "_" <variant> )?
# <ISO_3166_code> := 2-letter country code,
# as in http://www.unicode.org/unicode/onlinedat/countries.html
# <ISO_639_code> := 2-letter code,
# as in http://www.unicode.org/unicode/onlinedat/languages.html
# <context> := "FINAL" | "NON_FINAL" | "MODERN" | "NON_MODERN"
#
# A condition list overrides the normal behavior if any of the listed conditions is true.
# FINAL: The letter is not followed by a letter of category L* (e.g. Ll, Lt, Lu, Lm, or Lo).
# MODERN: The mapping is only used for modern text.
# Conditions preceded by "NON_" represent the negation of the condition
#
# New contexts may be added in the future.
# Parsers of this file must be prepared to deal with that situation.
# Additional whitespace around elements is optional. Blank lines are ignored in parsing.
# On any line, all text following "#" is a comment, and are ignored in parsing.
# ================================================================================
# ================================================================================
# Unconditional mappings
# ================================================================================
# The German es-zed is special--the normal mapping is to SS.
# Note: the titlecase should never occur in practice. It is equal to titlecase(uppercase(<es-zed>))
00DF; 00DF; 0053 0073; 0053 0053; # LATIN SMALL LETTER SHARP S
# Ligatures
FB00; FB00; 0046 0066; 0046 0046; # LATIN SMALL LIGATURE FF
FB01; FB01; 0046 0069; 0046 0049; # LATIN SMALL LIGATURE FI
FB02; FB02; 0046 006C; 0046 004C; # LATIN SMALL LIGATURE FL
FB03; FB03; 0046 0066 0069; 0046 0046 0049; # LATIN SMALL LIGATURE FFI
FB04; FB04; 0046 0066 006C; 0046 0046 004C; # LATIN SMALL LIGATURE FFL
FB05; FB05; 0053 0074; 0053 0054; # LATIN SMALL LIGATURE LONG S T
FB06; FB06; 0053 0074; 0053 0054; # LATIN SMALL LIGATURE ST
0587; 0587; 0535 0582; 0535 0552; # ARMENIAN SMALL LIGATURE ECH YIWN
FB13; FB13; 0544 0576; 0544 0546; # ARMENIAN SMALL LIGATURE MEN NOW
FB14; FB14; 0544 0565; 0544 0535; # ARMENIAN SMALL LIGATURE MEN ECH
FB15; FB15; 0544 056B; 0544 053B; # ARMENIAN SMALL LIGATURE MEN INI
FB16; FB16; 054E 0576; 054E 0546; # ARMENIAN SMALL LIGATURE VEW NOW
FB17; FB17; 0544 056D; 0544 053D; # ARMENIAN SMALL LIGATURE MEN XEH
# No corresponding uppercase precomposed character
0149; 0149; 02BC 006E; 02BC 004E; # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
0390; 0390; 0399 0308 0301; 0399 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
03B0; 03B0; 03A5 0308 0301; 03A5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
01F0; 01F0; 004A 030C; 004A 030C; # LATIN SMALL LETTER J WITH CARON
1E96; 1E96; 0048 0331; 0048 0331; # LATIN SMALL LETTER H WITH LINE BELOW
1E97; 1E97; 0054 0308; 0054 0308; # LATIN SMALL LETTER T WITH DIAERESIS
1E98; 1E98; 0057 030A; 0057 030A; # LATIN SMALL LETTER W WITH RING ABOVE
1E99; 1E99; 0059 030A; 0059 030A; # LATIN SMALL LETTER Y WITH RING ABOVE
1E9A; 1E9A; 0041 02BE; 0041 02BE; # LATIN SMALL LETTER A WITH RIGHT HALF RING
1F50; 1F50; 03A5 0313; 03A5 0313; # GREEK SMALL LETTER UPSILON WITH PSILI
1F52; 1F52; 03A5 0313 0300; 03A5 0313 0300; # GREEK SMALL LETTER UPSILON WITH PSILI AND VARIA
1F54; 1F54; 03A5 0313 0301; 03A5 0313 0301; # GREEK SMALL LETTER UPSILON WITH PSILI AND OXIA
1F56; 1F56; 03A5 0313 0342; 03A5 0313 0342; # GREEK SMALL LETTER UPSILON WITH PSILI AND PERISPOMENI
1FB6; 1FB6; 0391 0342; 0391 0342; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI
1FC6; 1FC6; 0397 0342; 0397 0342; # GREEK SMALL LETTER ETA WITH PERISPOMENI
1FD2; 1FD2; 0399 0308 0300; 0399 0308 0300; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND VARIA
1FD3; 1FD3; 0399 0308 0301; 0399 0308 0301; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND OXIA
1FD6; 1FD6; 0399 0342; 0399 0342; # GREEK SMALL LETTER IOTA WITH PERISPOMENI
1FD7; 1FD7; 0399 0308 0342; 0399 0308 0342; # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND PERISPOMENI
1FE2; 1FE2; 03A5 0308 0300; 03A5 0308 0300; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND VARIA
1FE3; 1FE3; 03A5 0308 0301; 03A5 0308 0301; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND OXIA
1FE4; 1FE4; 03A1 0313; 03A1 0313; # GREEK SMALL LETTER RHO WITH PSILI
1FE6; 1FE6; 03A5 0342; 03A5 0342; # GREEK SMALL LETTER UPSILON WITH PERISPOMENI
1FE7; 1FE7; 03A5 0308 0342; 03A5 0308 0342; # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND PERISPOMENI
1FF6; 1FF6; 03A9 0342; 03A9 0342; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI
# IMPORTANT-when capitalizing iota-subscript (0345)
# It MUST be in normalized form--moved to the end of any sequence of combining marks.
# This is because logically it represents a following base character!
# E.g. <iota_subscript> (<Mn> | <Mc> | <Me>)+ => (<Mn> | <Mc> | <Me>)+ <iota_subscript>
# It should never be the first character in a word, so in titlecasing it can be left as is.
# The following cases are already in the UnicodeData file, so are only commented here.
# 0345; 0345; 0345; 0399; # COMBINING GREEK YPOGEGRAMMENI
# All letters with YPOGEGRAMMENI (iota-subscript) or PROSGEGRAMMENI (iota adscript)
# have special uppercases.
# Note: characters with PROSGEGRAMMENI are actually titlecase, not uppercase!
1F80; 1F80; 1F88; 1F08 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI
1F81; 1F81; 1F89; 1F09 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI
1F82; 1F82; 1F8A; 1F0A 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1F83; 1F83; 1F8B; 1F0B 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1F84; 1F84; 1F8C; 1F0C 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1F85; 1F85; 1F8D; 1F0D 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1F86; 1F86; 1F8E; 1F0E 0399; # GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1F87; 1F87; 1F8F; 1F0F 0399; # GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1F88; 1F80; 1F88; 1F08 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI
1F89; 1F81; 1F89; 1F09 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI
1F8A; 1F82; 1F8A; 1F0A 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1F8B; 1F83; 1F8B; 1F0B 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1F8C; 1F84; 1F8C; 1F0C 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1F8D; 1F85; 1F8D; 1F0D 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1F8E; 1F86; 1F8E; 1F0E 0399; # GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1F8F; 1F87; 1F8F; 1F0F 0399; # GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1F90; 1F90; 1F98; 1F28 0399; # GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI
1F91; 1F91; 1F99; 1F29 0399; # GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI
1F92; 1F92; 1F9A; 1F2A 0399; # GREEK SMALL LETTER ETA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1F93; 1F93; 1F9B; 1F2B 0399; # GREEK SMALL LETTER ETA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1F94; 1F94; 1F9C; 1F2C 0399; # GREEK SMALL LETTER ETA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1F95; 1F95; 1F9D; 1F2D 0399; # GREEK SMALL LETTER ETA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1F96; 1F96; 1F9E; 1F2E 0399; # GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1F97; 1F97; 1F9F; 1F2F 0399; # GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1F98; 1F90; 1F98; 1F28 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI
1F99; 1F91; 1F99; 1F29 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI
1F9A; 1F92; 1F9A; 1F2A 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1F9B; 1F93; 1F9B; 1F2B 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1F9C; 1F94; 1F9C; 1F2C 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1F9D; 1F95; 1F9D; 1F2D 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1F9E; 1F96; 1F9E; 1F2E 0399; # GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1F9F; 1F97; 1F9F; 1F2F 0399; # GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1FA0; 1FA0; 1FA8; 1F68 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI
1FA1; 1FA1; 1FA9; 1F69 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI
1FA2; 1FA2; 1FAA; 1F6A 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA AND YPOGEGRAMMENI
1FA3; 1FA3; 1FAB; 1F6B 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA AND YPOGEGRAMMENI
1FA4; 1FA4; 1FAC; 1F6C 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA AND YPOGEGRAMMENI
1FA5; 1FA5; 1FAD; 1F6D 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA AND YPOGEGRAMMENI
1FA6; 1FA6; 1FAE; 1F6E 0399; # GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI AND YPOGEGRAMMENI
1FA7; 1FA7; 1FAF; 1F6F 0399; # GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI AND YPOGEGRAMMENI
1FA8; 1FA0; 1FA8; 1F68 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI
1FA9; 1FA1; 1FA9; 1F69 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI
1FAA; 1FA2; 1FAA; 1F6A 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA AND PROSGEGRAMMENI
1FAB; 1FA3; 1FAB; 1F6B 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA AND PROSGEGRAMMENI
1FAC; 1FA4; 1FAC; 1F6C 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA AND PROSGEGRAMMENI
1FAD; 1FA5; 1FAD; 1F6D 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA AND PROSGEGRAMMENI
1FAE; 1FA6; 1FAE; 1F6E 0399; # GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI AND PROSGEGRAMMENI
1FAF; 1FA7; 1FAF; 1F6F 0399; # GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI AND PROSGEGRAMMENI
1FB3; 1FB3; 1FBC; 0391 0399; # GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI
1FBC; 1FB3; 1FBC; 0391 0399; # GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI
1FC3; 1FC3; 1FCC; 0397 0399; # GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI
1FCC; 1FC3; 1FCC; 0397 0399; # GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI
1FF3; 1FF3; 1FFC; 03A9 0399; # GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI
1FFC; 1FF3; 1FFC; 03A9 0399; # GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI
# Some characters with YPOGEGRAMMENI are also have no corresponding titlecases
1FB2; 1FB2; 1FBA 0345; 1FBA 0399; # GREEK SMALL LETTER ALPHA WITH VARIA AND YPOGEGRAMMENI
1FB4; 1FB4; 0386 0345; 0386 0399; # GREEK SMALL LETTER ALPHA WITH OXIA AND YPOGEGRAMMENI
1FC2; 1FC2; 1FCA 0345; 1FCA 0399; # GREEK SMALL LETTER ETA WITH VARIA AND YPOGEGRAMMENI
1FC4; 1FC4; 0389 0345; 0389 0399; # GREEK SMALL LETTER ETA WITH OXIA AND YPOGEGRAMMENI
1FF2; 1FF2; 1FFA 0345; 1FFA 0399; # GREEK SMALL LETTER OMEGA WITH VARIA AND YPOGEGRAMMENI
1FF4; 1FF4; 038F 0345; 038F 0399; # GREEK SMALL LETTER OMEGA WITH OXIA AND YPOGEGRAMMENI
1FB7; 1FB7; 0391 0342 0345; 0391 0342 0399; # GREEK SMALL LETTER ALPHA WITH PERISPOMENI AND YPOGEGRAMMENI
1FC7; 1FC7; 0397 0342 0345; 0397 0342 0399; # GREEK SMALL LETTER ETA WITH PERISPOMENI AND YPOGEGRAMMENI
1FF7; 1FF7; 03A9 0342 0345; 03A9 0342 0399; # GREEK SMALL LETTER OMEGA WITH PERISPOMENI AND YPOGEGRAMMENI
# ================================================================================
# Conditional mappings
# ================================================================================
# Special case for final form of sigma
03A3; 03C2; 03A3; 03A3; FINAL; # GREEK CAPITAL LETTER SIGMA
# Note: the following cases for non-final are already in the UnicodeData file.
# 03A3; 03C3; 03A3; 03A3; # GREEK CAPITAL LETTER SIGMA
# 03C3; 03C3; 03A3; 03A3; # GREEK SMALL LETTER SIGMA
# 03C2; 03C2; 03A3; 03A3; # GREEK SMALL LETTER FINAL SIGMA
# Note: the following cases are not included, since they would normalize in lowercasing
# 03C3; 03C2; 03A3; 03A3; FINAL; # GREEK SMALL LETTER SIGMA
# 03C2; 03C3; 03A3; 03A3; NON_FINAL; # GREEK SMALL LETTER FINAL SIGMA
# ================================================================================
# Locale-sensitive mappings
# ================================================================================
# Turkish
0049; 0131; 0049; 0049; TR; # LATIN CAPITAL LETTER I
0069; 0069; 0130; 0130; TR; # LATIN SMALL LETTER I
# Note: the following cases are already in the UnicodeData file.
# 0131; 0131; 0049; 0049; TR; # LATIN SMALL LETTER DOTLESS I
# 0130; 0069; 0130; 0130; TR; # LATIN CAPITAL LETTER I WITH DOT ABOVE

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More