diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-06-05 01:19:53 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-06-05 01:19:53 +0300 |
commit | 7087cd30afbb6f15c55b8adbc270776f35d4fefb (patch) | |
tree | fd57228a67d784149034ffc064f02bb10f138b00 /src/ellinika | |
parent | 70e1a84f121d0199f7fb140525b0c62dc138e0e4 (diff) | |
download | ellinika-7087cd30afbb6f15c55b8adbc270776f35d4fefb.tar.gz ellinika-7087cd30afbb6f15c55b8adbc270776f35d4fefb.tar.bz2 |
Bugfixes.
* data/db.struct (verb): Minor fix.
* src/ellinika/elchr.c: Fix base of lower case epsilon.
* src/ellinika/elmorph.c (_elstr_alloc_empty): New function.
(_elstr_alloc): Take additional argument. All uses changed.
(_elstr_concat): New function.
(_elstr_print): Correctly print objects with NULL sylmap.
(elstr?): New function.
(elstr-append): New function.
Diffstat (limited to 'src/ellinika')
-rw-r--r-- | src/ellinika/elchr.c | 4 | ||||
-rw-r--r-- | src/ellinika/elmorph.c | 95 |
2 files changed, 91 insertions, 8 deletions
diff --git a/src/ellinika/elchr.c b/src/ellinika/elchr.c index 10ea72d..3142b6f 100644 --- a/src/ellinika/elchr.c +++ b/src/ellinika/elchr.c @@ -210,13 +210,13 @@ struct char_info_st el_basic_ctype[] = { { 0x03A7, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03C7, 600 }, /* Χ */ { 0x03A8, CHF_CONSONANT|CHF_UPPER|CHF_NUMERIC, 0, 0x03C8, 700 }, /* Ψ */ { 0x03A9, CHF_VOWEL|CHF_UPPER|CHF_NUMERIC, 0, 0x03C9, 800, 0x038F }, /* Ω */ { 0x03AA, CHF_VOWEL|CHF_UPPER|CHF_TREMA|CHF_DIPH2, 0x0399, 0x03CA }, /* Ϊ */ { 0x03AB, CHF_VOWEL|CHF_UPPER|CHF_TREMA, 0x03A5, 0x03CB }, /* Ϋ */ { 0x03AC, CHF_VOWEL|CHF_LOWER|CHF_OXEIA, 0x03B1, 0x0386 }, /* ά */ - { 0x03AD, CHF_VOWEL|CHF_LOWER|CHF_OXEIA, 0x03B4, 0x0388 }, /* έ */ + { 0x03AD, CHF_VOWEL|CHF_LOWER|CHF_OXEIA, 0x03B5, 0x0388 }, /* έ */ { 0x03AE, CHF_VOWEL|CHF_LOWER|CHF_OXEIA|CHF_DIPH2, 0x03B7, 0x0389 }, /* ή */ { 0x03AF, CHF_VOWEL|CHF_LOWER|CHF_OXEIA|CHF_DIPH2, 0x03B9, 0x038A }, /* ί */ { 0x03B0, CHF_VOWEL|CHF_OXEIA|CHF_TREMA, 0x03C5, 0, 0, 0, 0, 0x03CB }, /* ΰ */ { 0x03B1, CHF_VOWEL|CHF_LOWER|CHF_NUMERIC|CHF_DIPH1, 0, 0x0391, 1, 0x03AC }, /* α */ { 0x03B2, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x0392, 2 }, /* β */ { 0x03B3, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x0393, 3 }, /* γ */ @@ -229,13 +229,13 @@ struct char_info_st el_basic_ctype[] = { { 0x03BA, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x039A, 20 }, /* κ */ { 0x03BB, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x039B, 30 }, /* λ */ { 0x03BC, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x039C, 40 }, /* μ */ { 0x03BD, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x039D, 50 }, /* ν */ { 0x03BE, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x039E, 60 }, /* ξ */ - { 0x03BF, CHF_VOWEL|CHF_LOWER|CHF_NUMERIC, 0, 0x039F, 70, 0x03CC }, /* ο */ + { 0x03BF, CHF_VOWEL|CHF_LOWER|CHF_NUMERIC|CHF_DIPH1, 0, 0x039F, 70, 0x03CC }, /* ο */ { 0x03C0, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x03A0, 80 }, /* π */ { 0x03C1, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x03A1, 100 }, /* ρ */ { 0x03C2, CHF_CONSONANT|CHF_LOWER, 0, 0x03A3 }, /* ς */ { 0x03C3, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x03A3, 200 }, /* σ */ { 0x03C4, CHF_CONSONANT|CHF_LOWER|CHF_NUMERIC, 0, 0x03A4, 300 }, /* τ */ { 0x03C5, CHF_VOWEL|CHF_LOWER|CHF_NUMERIC|CHF_DIPH2, 0, 0x03A5, 400, 0x03CD }, /* υ */ diff --git a/src/ellinika/elmorph.c b/src/ellinika/elmorph.c index 6ff5f01..75e42f9 100644 --- a/src/ellinika/elmorph.c +++ b/src/ellinika/elmorph.c @@ -72,25 +72,37 @@ _elstr_syllabize(struct elstr *elstr) elstr->nsyl = nsyl; elstr->acc_pos = accchr; elstr->acc_syl = nsyl - accsyl; } static SCM -_elstr_alloc(const char *instr) +_elstr_alloc_empty(struct elstr **pelstr) +{ + struct elstr *elstr; + + elstr = scm_gc_malloc(sizeof(*elstr), "Elstr"); + memset(elstr, 0, sizeof(*elstr)); + *pelstr = elstr; + SCM_RETURN_NEWSMOB(_elstr_tag, elstr); +} + +static SCM +_elstr_alloc(const char *instr, int syl) { struct elstr *elstr; unsigned *wptr; size_t wlen; if (utf8_mbstr_to_wc(instr, &wptr, &wlen)) return SCM_EOL; elstr = scm_gc_malloc(sizeof(*elstr), "Elstr"); elstr->str = wptr; elstr->len = wlen; elstr->sylmap = NULL; + if (syl) _elstr_syllabize(elstr); SCM_RETURN_NEWSMOB(_elstr_tag, elstr); } static SCM @@ -114,12 +126,28 @@ _elstr_dup(struct elstr *elstr) sizeof(elstr->sylmap[0]) * elstr->nsyl); elnew->acc_syl = elstr->acc_syl; elnew->acc_pos = elstr->acc_pos; SCM_RETURN_NEWSMOB(_elstr_tag, elnew); } +static void +_elstr_concat(struct elstr *dest, struct elstr *src, const char *func_name) +{ + unsigned *wp; + + wp = realloc(dest->str, + sizeof(dest->str[0]) * (dest->len + src->len)); + if (!wp) + scm_memory_error(func_name); + dest->str = wp; + memcpy(dest->str + dest->len, + src->str, + sizeof(src->str[0]) * src->len); + dest->len += src->len; +} + static scm_sizet _elstr_free(SCM smob) { struct elstr *elstr = (struct elstr *) SCM_CDR(smob); free(elstr->str); free(elstr->sylmap); @@ -131,13 +159,15 @@ static int _elstr_print(SCM smob, SCM port, scm_print_state *pstate) { struct elstr *elstr = (struct elstr *) SCM_CDR(smob); int i, j, an; char *s; - scm_puts("#<elstr ``", port); + scm_puts("#<elstr ", port); + if (elstr->sylmap) { + scm_puts("``", port); an = elstr->nsyl - elstr->acc_syl; if (an == 0) scm_puts("[", port); for (i = j = 0; i < elstr->len; i++) { char r[6]; int n; @@ -154,46 +184,67 @@ _elstr_print(SCM smob, SCM port, scm_print_state *pstate) continue; r[n] = 0; scm_puts(r, port); } if (j == an) scm_puts("]", port); + } else { + scm_puts("[NS] ``", port); + for (i = j = 0; i < elstr->len; i++) { + char r[6]; + int n; + n = utf8_wctomb(r, elstr->str[i]); + if (n == -1) + continue; + r[n] = 0; + scm_puts(r, port); + } + } scm_puts("''>", port); return 1; } static void _elstr_init() { _elstr_tag = scm_make_smob_type("Elstr", sizeof(struct elstr)); scm_set_smob_free(_elstr_tag, _elstr_free); scm_set_smob_print(_elstr_tag, _elstr_print); } +#define scm_is_elstr(s) (!SCM_IMP(s) && SCM_CELL_TYPE(s) == _elstr_tag) + +SCM_DEFINE_PUBLIC(scm_elstr_p, "elstr?", 1, 0, 0, + (SCM string), +"Return true if STRING is an elstr\n") +#define FUNC_NAME s_scm_elstr_p +{ + return scm_is_elstr(string) ? SCM_BOOL_T : SCM_BOOL_F; +} +#undef FUNC_NAME + SCM_DEFINE_PUBLIC(scm_string__elstr, "string->elstr", 1, 0, 0, (SCM string), "Create new ELSTR from STRING\n") #define FUNC_NAME s_scm_string__elstr { char *str; SCM scm; SCM_ASSERT(scm_is_string(string), string, SCM_ARG1, FUNC_NAME); str = scm_to_locale_string(string); - scm = _elstr_alloc(str); + scm = _elstr_alloc(str, 1); free(str); if (scm == SCM_EOL) scm_misc_error(FUNC_NAME, "Invalid input string: ~S", scm_list_1(string)); return scm; } #undef FUNC_NAME -#define scm_is_elstr(s) (!SCM_IMP(s) && SCM_CELL_TYPE(s) == _elstr_tag) - SCM_DEFINE_PUBLIC(scm_elstr__string, "elstr->string", 1, 0, 0, (SCM el), "Convert EL to a STRING\n") #define FUNC_NAME s_scm_elstr__string { struct elstr *elstr; @@ -472,13 +523,13 @@ _elstr_set_accent(SCM el, SCM n, int destructive, const char *func_name) SCM_ASSERT(scm_is_elstr(el), el, SCM_ARG1, func_name); SCM_ASSERT(scm_is_integer(n), n, SCM_ARG2, func_name); elstr = (struct elstr*) SCM_CDR(el); num = scm_to_uint(n); if (num > elstr->nsyl) scm_misc_error(func_name, - "cannot get syllable #~S: not enough syllables: ~S", + "cannot set accent on syllable #~S: not enough syllables: ~S", scm_list_2(el, n)); acc_num = elstr->nsyl - num; if (acc_num == 0) start = 0; else start = elstr->sylmap[acc_num - 1] + 1; @@ -752,12 +803,44 @@ SCM_DEFINE_PUBLIC(scm_elstr_index, "elstr-index", if (p) return scm_from_int(p - elstr->str); return SCM_BOOL_F; } #undef FUNC_NAME +SCM_DEFINE_PUBLIC(scm_elstr_append, "elstr-append", + 0, 0, 1, + (SCM rest), +"") +#define FUNC_NAME s_scm_elstr_append +{ + SCM ret = _elstr_alloc("", 0); + struct elstr *elstr = (struct elstr*) SCM_CDR(ret); + + for (; !scm_is_null(rest); rest = SCM_CDR(rest)) { + SCM val = SCM_CAR(rest); + if (scm_is_elstr(val)) { + struct elstr *elt = (struct elstr*) SCM_CDR(val); + _elstr_concat(elstr, elt, FUNC_NAME); + } else if (scm_is_string(val)) { + char *s = scm_to_locale_string(val); + if (s[0]) { + SCM tmp = _elstr_alloc(s, 0); + free(s); + _elstr_concat(elstr, + (struct elstr*) SCM_CDR(tmp), + FUNC_NAME); + } else + free(s); + } else + scm_wrong_type_arg(FUNC_NAME, SCM_ARGn, rest); + } + _elstr_syllabize(elstr); + return ret; +} +#undef FUNC_NAME + void scm_init_ellinika_elmorph_module() { int i; |