summaryrefslogtreecommitdiffabout
path: root/src/ellinika
authorSergey Poznyakoff <gray@gnu.org.ua>2011-06-04 22:19:53 (GMT)
committer Sergey Poznyakoff <gray@gnu.org.ua>2011-06-04 22:19:53 (GMT)
commit7087cd30afbb6f15c55b8adbc270776f35d4fefb (patch) (side-by-side diff)
treefd57228a67d784149034ffc064f02bb10f138b00 /src/ellinika
parent70e1a84f121d0199f7fb140525b0c62dc138e0e4 (diff)
downloadellinika-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') (more/less context) (ignore whitespace changes)
-rw-r--r--src/ellinika/elchr.c4
-rw-r--r--src/ellinika/elmorph.c141
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
@@ -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
@@ -45,13 +45,13 @@ _elstr_syllabize(struct elstr *elstr)
int acc = 0;
if (!elstr->sylmap)
elstr->sylmap = scm_gc_malloc(sizeof(sylmap[0])*elstr->len,
"syllable map");
sylmap = elstr->sylmap;
-
+
for (i = 0; i < elstr->len; i++) {
int nstate;
if (elchr_getaccent(elstr->str[i])) {
accsyl = nsyl;
accchr = i;
@@ -72,26 +72,38 @@ _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;
- _elstr_syllabize(elstr);
+ if (syl)
+ _elstr_syllabize(elstr);
SCM_RETURN_NEWSMOB(_elstr_tag, elstr);
}
static SCM
_elstr_dup(struct elstr *elstr)
@@ -113,13 +125,29 @@ _elstr_dup(struct elstr *elstr)
memcpy(elnew->sylmap, elstr->sylmap,
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,69 +159,92 @@ 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);
- 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);
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;
@@ -751,12 +802,44 @@ SCM_DEFINE_PUBLIC(scm_elstr_index, "elstr-index",
free(wtmp);
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;

Return to:

Send suggestions and report system problems to the System administrator.