* 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:
parent
4465d9277f
commit
c3ac87e8fc
350
headers/os/locale/Catalog.h
Normal file
350
headers/os/locale/Catalog.h
Normal 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_ */
|
120
headers/os/locale/CatalogInAddOn.h
Normal file
120
headers/os/locale/CatalogInAddOn.h
Normal 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_ */
|
119
headers/os/locale/Collator.h
Normal file
119
headers/os/locale/Collator.h
Normal 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_ */
|
75
headers/os/locale/Country.h
Normal file
75
headers/os/locale/Country.h
Normal 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_ */
|
47
headers/os/locale/Currency.h
Normal file
47
headers/os/locale/Currency.h
Normal 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_
|
197
headers/os/locale/DefaultCatalog.h
Normal file
197
headers/os/locale/DefaultCatalog.h
Normal 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_ */
|
56
headers/os/locale/FloatFormat.h
Normal file
56
headers/os/locale/FloatFormat.h
Normal 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_
|
39
headers/os/locale/FloatFormatImpl.h
Normal file
39
headers/os/locale/FloatFormatImpl.h
Normal 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_
|
54
headers/os/locale/FloatFormatParameters.h
Normal file
54
headers/os/locale/FloatFormatParameters.h
Normal 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_
|
48
headers/os/locale/Format.h
Normal file
48
headers/os/locale/Format.h
Normal 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_
|
20
headers/os/locale/FormatImpl.h
Normal file
20
headers/os/locale/FormatImpl.h
Normal 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_
|
39
headers/os/locale/FormatParameters.h
Normal file
39
headers/os/locale/FormatParameters.h
Normal 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_
|
160
headers/os/locale/GenericNumberFormat.h
Normal file
160
headers/os/locale/GenericNumberFormat.h
Normal 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_
|
61
headers/os/locale/IntegerFormat.h
Normal file
61
headers/os/locale/IntegerFormat.h
Normal 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_
|
38
headers/os/locale/IntegerFormatImpl.h
Normal file
38
headers/os/locale/IntegerFormatImpl.h
Normal 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_
|
22
headers/os/locale/IntegerFormatParameters.h
Normal file
22
headers/os/locale/IntegerFormatParameters.h
Normal 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_
|
43
headers/os/locale/Language.h
Normal file
43
headers/os/locale/Language.h
Normal 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
113
headers/os/locale/Locale.h
Normal 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_ */
|
12
headers/os/locale/LocaleBuild.h
Normal file
12
headers/os/locale/LocaleBuild.h
Normal 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_ */
|
84
headers/os/locale/LocaleRoster.h
Normal file
84
headers/os/locale/LocaleRoster.h
Normal 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_ */
|
108
headers/os/locale/LocaleStrings.h
Normal file
108
headers/os/locale/LocaleStrings.h
Normal 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_ */
|
23
headers/os/locale/NumberFormat.h
Normal file
23
headers/os/locale/NumberFormat.h
Normal 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_
|
22
headers/os/locale/NumberFormatImpl.h
Normal file
22
headers/os/locale/NumberFormatImpl.h
Normal 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_
|
66
headers/os/locale/NumberFormatParameters.h
Normal file
66
headers/os/locale/NumberFormatParameters.h
Normal 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_
|
235
headers/os/locale/UnicodeChar.h
Normal file
235
headers/os/locale/UnicodeChar.h
Normal 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
86
headers/posix/langinfo.h
Normal 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
19
headers/posix/monetary.h
Normal 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_ */
|
23
headers/private/locale/PropertyFile.h
Normal file
23
headers/private/locale/PropertyFile.h
Normal 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 */
|
25
headers/private/locale/UnicodeProperties.h
Normal file
25
headers/private/locale/UnicodeProperties.h
Normal 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_ */
|
4
src/add-ons/locale/Jamfile
Normal file
4
src/add-ons/locale/Jamfile
Normal file
@ -0,0 +1,4 @@
|
||||
SubDir LOCALE_TOP add-ons ;
|
||||
|
||||
SubInclude LOCALE_TOP add-ons catalogs ;
|
||||
SubInclude LOCALE_TOP add-ons collators ;
|
3
src/add-ons/locale/catalogs/Jamfile
Normal file
3
src/add-ons/locale/catalogs/Jamfile
Normal file
@ -0,0 +1,3 @@
|
||||
SubDir LOCALE_TOP add-ons catalogs ;
|
||||
|
||||
SubInclude LOCALE_TOP add-ons catalogs zeta ;
|
89
src/add-ons/locale/catalogs/zeta/Catalog.cpp
Normal file
89
src/add-ons/locale/catalogs/zeta/Catalog.cpp
Normal 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
|
3
src/add-ons/locale/catalogs/zeta/Jamfile
Normal file
3
src/add-ons/locale/catalogs/zeta/Jamfile
Normal file
@ -0,0 +1,3 @@
|
||||
SubDir LOCALE_TOP add-ons catalogs zeta ;
|
||||
|
||||
AddOn zeta : Catalog.cpp : be liblocale.so ;
|
272
src/add-ons/locale/collators/French.cpp
Normal file
272
src/add-ons/locale/collators/French.cpp
Normal 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();
|
||||
}
|
131
src/add-ons/locale/collators/GermanDIN-2.cpp
Normal file
131
src/add-ons/locale/collators/GermanDIN-2.cpp
Normal 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();
|
||||
}
|
15
src/add-ons/locale/collators/Jamfile
Normal file
15
src/add-ons/locale/collators/Jamfile
Normal 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
10
src/bin/locale/Jamfile
Normal 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 ;
|
277
src/bin/locale/collectcatkeys.cpp
Normal file
277
src/bin/locale/collectcatkeys.cpp
Normal 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;
|
||||
}
|
76
src/bin/locale/dumpcatalog.cpp
Normal file
76
src/bin/locale/dumpcatalog.cpp
Normal 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;
|
||||
}
|
174
src/bin/locale/linkcatkeys.cpp
Normal file
174
src/bin/locale/linkcatkeys.cpp
Normal 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;
|
||||
}
|
13
src/data/etc/locale/languages/Jamfile
Normal file
13
src/data/etc/locale/languages/Jamfile
Normal 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) ;
|
||||
}
|
||||
}
|
49
src/data/etc/locale/languages/deutsch.language
Normal file
49
src/data/etc/locale/languages/deutsch.language
Normal 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
|
||||
|
49
src/data/etc/locale/languages/francais.language
Normal file
49
src/data/etc/locale/languages/francais.language
Normal 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
421
src/kits/locale/Catalog.cpp
Normal 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
|
475
src/kits/locale/Collator.cpp
Normal file
475
src/kits/locale/Collator.cpp
Normal 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
261
src/kits/locale/Country.cpp
Normal 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;
|
||||
}
|
||||
|
192
src/kits/locale/Currency.cpp
Normal file
192
src/kits/locale/Currency.cpp
Normal 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;
|
||||
}
|
||||
|
746
src/kits/locale/DefaultCatalog.cpp
Normal file
746
src/kits/locale/DefaultCatalog.cpp
Normal 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
|
61
src/kits/locale/FloatFormat.cpp
Normal file
61
src/kits/locale/FloatFormat.cpp
Normal 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);
|
||||
}
|
||||
|
28
src/kits/locale/FloatFormatImpl.cpp
Normal file
28
src/kits/locale/FloatFormatImpl.cpp
Normal 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();
|
||||
}
|
||||
|
198
src/kits/locale/FloatFormatParameters.cpp
Normal file
198
src/kits/locale/FloatFormatParameters.cpp
Normal 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;
|
||||
}
|
||||
|
28
src/kits/locale/Format.cpp
Normal file
28
src/kits/locale/Format.cpp
Normal 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)
|
||||
{
|
||||
}
|
||||
|
12
src/kits/locale/FormatImpl.cpp
Normal file
12
src/kits/locale/FormatImpl.cpp
Normal file
@ -0,0 +1,12 @@
|
||||
#include <FormatImpl.h>
|
||||
|
||||
// constructor
|
||||
BFormatImpl::BFormatImpl()
|
||||
{
|
||||
}
|
||||
|
||||
// destructor
|
||||
BFormatImpl::~BFormatImpl()
|
||||
{
|
||||
}
|
||||
|
96
src/kits/locale/FormatParameters.cpp
Normal file
96
src/kits/locale/FormatParameters.cpp
Normal 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;
|
||||
}
|
||||
|
1528
src/kits/locale/GenericNumberFormat.cpp
Normal file
1528
src/kits/locale/GenericNumberFormat.cpp
Normal file
File diff suppressed because it is too large
Load Diff
61
src/kits/locale/IntegerFormat.cpp
Normal file
61
src/kits/locale/IntegerFormat.cpp
Normal 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);
|
||||
}
|
||||
|
28
src/kits/locale/IntegerFormatImpl.cpp
Normal file
28
src/kits/locale/IntegerFormatImpl.cpp
Normal 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();
|
||||
}
|
||||
|
48
src/kits/locale/IntegerFormatParameters.cpp
Normal file
48
src/kits/locale/IntegerFormatParameters.cpp
Normal 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
35
src/kits/locale/Jamfile
Normal 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
|
||||
;
|
216
src/kits/locale/Language.cpp
Normal file
216
src/kits/locale/Language.cpp
Normal 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];
|
||||
}
|
||||
|
156
src/kits/locale/LibraryInit.cpp
Normal file
156
src/kits/locale/LibraryInit.cpp
Normal 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
|
54
src/kits/locale/Locale.cpp
Normal file
54
src/kits/locale/Locale.cpp
Normal 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);
|
||||
}
|
601
src/kits/locale/LocaleRoster.cpp
Normal file
601
src/kits/locale/LocaleRoster.cpp
Normal 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;
|
||||
}
|
36
src/kits/locale/NumberFormat.cpp
Normal file
36
src/kits/locale/NumberFormat.cpp
Normal 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);
|
||||
}
|
||||
|
28
src/kits/locale/NumberFormatImpl.cpp
Normal file
28
src/kits/locale/NumberFormatImpl.cpp
Normal 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();
|
||||
}
|
||||
|
194
src/kits/locale/NumberFormatParameters.cpp
Normal file
194
src/kits/locale/NumberFormatParameters.cpp
Normal 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;
|
||||
}
|
||||
|
54
src/kits/locale/PropertyFile.cpp
Normal file
54
src/kits/locale/PropertyFile.cpp
Normal 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);
|
||||
}
|
||||
|
708
src/kits/locale/UnicodeChar.cpp
Normal file
708
src/kits/locale/UnicodeChar.cpp
Normal 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
54
src/kits/locale/adler32.c
Normal 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
30
src/kits/locale/cat.cpp
Normal 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;
|
||||
}
|
||||
|
20
src/kits/locale/langinfo.cpp
Normal file
20
src/kits/locale/langinfo.cpp
Normal 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
179
src/kits/locale/makefile
Normal 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
181
src/kits/locale/strfmon.cpp
Normal 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;
|
||||
}
|
||||
|
8
src/preferences/locale/Jamfile
Normal file
8
src/preferences/locale/Jamfile
Normal file
@ -0,0 +1,8 @@
|
||||
SubDir LOCALE_TOP preferences ;
|
||||
|
||||
AddResources Locale : Locale.rsrc ;
|
||||
|
||||
Application Locale :
|
||||
Locale.cpp
|
||||
LocaleWindow.cpp
|
||||
: be liblocale.so ;
|
198
src/preferences/locale/Locale.cpp
Normal file
198
src/preferences/locale/Locale.cpp
Normal 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;
|
||||
}
|
25
src/preferences/locale/Locale.h
Normal file
25
src/preferences/locale/Locale.h
Normal 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 */
|
125
src/preferences/locale/LocaleWindow.cpp
Normal file
125
src/preferences/locale/LocaleWindow.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
|
25
src/preferences/locale/LocaleWindow.h
Normal file
25
src/preferences/locale/LocaleWindow.h
Normal 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 */
|
28
src/tests/kits/locale/Jamfile
Normal file
28
src/tests/kits/locale/Jamfile
Normal 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 ;
|
204
src/tests/kits/locale/catalogSpeed.cpp
Normal file
204
src/tests/kits/locale/catalogSpeed.cpp
Normal 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;
|
||||
}
|
197
src/tests/kits/locale/catalogTest.cpp
Normal file
197
src/tests/kits/locale/catalogTest.cpp
Normal 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;
|
||||
}
|
158
src/tests/kits/locale/catalogTestAddOn.cpp
Normal file
158
src/tests/kits/locale/catalogTestAddOn.cpp
Normal 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();
|
||||
}
|
138
src/tests/kits/locale/collatorSpeed.cpp
Normal file
138
src/tests/kits/locale/collatorSpeed.cpp
Normal 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",
|
||||
"wÖ",
|
||||
"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;
|
||||
}
|
||||
|
210
src/tests/kits/locale/collatorTest.cpp
Normal file
210
src/tests/kits/locale/collatorTest.cpp
Normal 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",
|
||||
"wÖ",
|
||||
"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);
|
||||
}
|
||||
}
|
||||
|
106
src/tests/kits/locale/genericNumberFormatTest.cpp
Normal file
106
src/tests/kits/locale/genericNumberFormatTest.cpp
Normal 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, ¶meters, number);
|
||||
parameters.SetFormatWidth(25);
|
||||
format_integer(" right aligned:", format, ¶meters, number);
|
||||
parameters.SetAlignment(B_ALIGN_FORMAT_LEFT);
|
||||
format_integer(" left aligned:", format, ¶meters, number);
|
||||
parameters.SetFormatWidth(1);
|
||||
parameters.SetAlignment(B_ALIGN_FORMAT_RIGHT);
|
||||
parameters.SetSignPolicy(B_USE_POSITIVE_SIGN);
|
||||
format_integer(" use plus:", format, ¶meters, number);
|
||||
parameters.SetSignPolicy(B_USE_SPACE_FOR_POSITIVE_SIGN);
|
||||
format_integer(" space for plus:", format, ¶meters, number);
|
||||
parameters.SetSignPolicy(B_USE_NEGATIVE_SIGN_ONLY);
|
||||
parameters.SetMinimalIntegerDigits(0);
|
||||
format_integer(" min digits 0:", format, ¶meters, number);
|
||||
parameters.SetMinimalIntegerDigits(5);
|
||||
format_integer(" min digits 5:", format, ¶meters, number);
|
||||
parameters.SetMinimalIntegerDigits(20);
|
||||
format_integer(" min digits 20:", format, ¶meters, number);
|
||||
parameters.SetMinimalIntegerDigits(30);
|
||||
format_integer(" min digits 30:", format, ¶meters, 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, ¶meters, 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;
|
||||
}
|
||||
|
104
src/tests/kits/locale/localeTest.cpp
Normal file
104
src/tests/kits/locale/localeTest.cpp
Normal 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",
|
||||
"wÖ", "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));
|
||||
}
|
||||
|
13
src/tests/kits/locale/number_format/Jamfile
Normal file
13
src/tests/kits/locale/number_format/Jamfile
Normal 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
|
||||
;
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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_
|
@ -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;
|
||||
}
|
@ -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
3
src/tools/locale/Jamfile
Normal file
@ -0,0 +1,3 @@
|
||||
SubDir LOCALE_TOP tools ;
|
||||
|
||||
SubInclude LOCALE_TOP tools genprops ;
|
5
src/tools/locale/genprops/Jamfile
Normal file
5
src/tools/locale/genprops/Jamfile
Normal 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 ;
|
71
src/tools/locale/genprops/PropertyFile.cpp
Normal file
71
src/tools/locale/genprops/PropertyFile.cpp
Normal 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;
|
||||
}
|
||||
|
24
src/tools/locale/genprops/PropertyFile.h
Normal file
24
src/tools/locale/genprops/PropertyFile.h
Normal 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 */
|
821
src/tools/locale/genprops/data/CaseFolding.txt
Normal file
821
src/tools/locale/genprops/data/CaseFolding.txt
Normal 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
|
||||
|
||||
|
245
src/tools/locale/genprops/data/Mirror.txt
Normal file
245
src/tools/locale/genprops/data/Mirror.txt
Normal 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
|
219
src/tools/locale/genprops/data/SpecialCasing.txt
Normal file
219
src/tools/locale/genprops/data/SpecialCasing.txt
Normal 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
|
10617
src/tools/locale/genprops/data/UnicodeData.txt
Normal file
10617
src/tools/locale/genprops/data/UnicodeData.txt
Normal file
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
Loading…
Reference in New Issue
Block a user