diff options
Diffstat (limited to 'src/ellinika')
-rw-r--r-- | src/ellinika/elchr.c | 4 | ||||
-rw-r--r-- | src/ellinika/elmorph.c | 141 |
2 files changed, 114 insertions, 31 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 @@ -215,3 +215,3 @@ struct char_info_st el_basic_ctype[] = { { 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 }, /* ή */ @@ -234,3 +234,3 @@ struct char_info_st el_basic_ctype[] = { - { 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 }, /* π */ 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 @@ -50,3 +50,3 @@ _elstr_syllabize(struct elstr *elstr) sylmap = elstr->sylmap; - + for (i = 0; i < elstr->len; i++) { @@ -77,3 +77,14 @@ _elstr_syllabize(struct elstr *elstr) 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) { @@ -90,3 +101,4 @@ _elstr_alloc(const char *instr) elstr->sylmap = NULL; - _elstr_syllabize(elstr); + if (syl) + _elstr_syllabize(elstr); @@ -118,3 +130,19 @@ _elstr_dup(struct elstr *elstr) } - + +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 @@ -136,25 +164,39 @@ _elstr_print(SCM smob, SCM port, scm_print_state *pstate) - scm_puts("#<elstr ``", 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; - - if (i == elstr->sylmap[j] + 1) { - if (j == an) - scm_puts("]", port); - scm_puts("-", port); - if (++j == an) - scm_puts("[", 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; + + if (i == elstr->sylmap[j] + 1) { + if (j == an) + scm_puts("]", port); + scm_puts("-", port); + if (++j == an) + scm_puts("[", port); + } + n = utf8_wctomb(r, elstr->str[i]); + if (n == -1) + 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); } - n = utf8_wctomb(r, elstr->str[i]); - if (n == -1) - continue; - r[n] = 0; - scm_puts(r, port); } - if (j == an) - scm_puts("]", port); scm_puts("''>", port); @@ -171,2 +213,13 @@ _elstr_init() +#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, @@ -181,3 +234,3 @@ SCM_DEFINE_PUBLIC(scm_string__elstr, "string->elstr", 1, 0, 0, str = scm_to_locale_string(string); - scm = _elstr_alloc(str); + scm = _elstr_alloc(str, 1); free(str); @@ -191,4 +244,2 @@ SCM_DEFINE_PUBLIC(scm_string__elstr, "string->elstr", 1, 0, 0, -#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, @@ -477,3 +528,3 @@ _elstr_set_accent(SCM el, SCM n, int destructive, const char *func_name) 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)); @@ -756,2 +807,34 @@ SCM_DEFINE_PUBLIC(scm_elstr_index, "elstr-index", #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 |