diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-06-05 13:56:34 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-06-05 13:56:34 +0300 |
commit | daca71a486490125471d0fb8d596d004485179bf (patch) | |
tree | d31ef54152a5ae3a20e53ff4c5a505ce4f7612fa /src | |
parent | 618724bfda07dfb1f8b61212da8f43e2eace95ba (diff) | |
download | ellinika-daca71a486490125471d0fb8d596d004485179bf.tar.gz ellinika-daca71a486490125471d0fb8d596d004485179bf.tar.bz2 |
Fix memory corruption, improve conjugator
* data/db.struct: Revamp conjugation support tables.
* scm/conjugator.scm: Improve irregular conjugation support.
* src/ellinika/elmorph.c (_elstr_syllabize): Use calloc.
Fix memory corruption.
(_elstr_dup): Don't allocate new sylmap if the source one is NULL.
(_elstr_free): Call scm_gc_free on elstr.
Diffstat (limited to 'src')
-rw-r--r-- | src/ellinika/elmorph.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/src/ellinika/elmorph.c b/src/ellinika/elmorph.c index 75e42f9..faeeb49 100644 --- a/src/ellinika/elmorph.c +++ b/src/ellinika/elmorph.c @@ -37,19 +37,22 @@ struct elstr { scm_t_bits _elstr_tag; static void _elstr_syllabize(struct elstr *elstr) { unsigned *sylmap; - unsigned i, nsyl = 0, accsyl = 0, accchr = 0; + unsigned i, nsyl = 0, accchr = 0; + int accsyl = -1; int dstate = 0; int acc = 0; - if (!elstr->sylmap) - elstr->sylmap = scm_gc_malloc(sizeof(sylmap[0])*elstr->len, - "syllable map"); + if (!elstr->sylmap) { + elstr->sylmap = calloc(elstr->len, sizeof(sylmap[0])); + if (!elstr->sylmap) + scm_memory_error("_elstr_syllabize"); + } sylmap = elstr->sylmap; for (i = 0; i < elstr->len; i++) { int nstate; if (elchr_getaccent(elstr->str[i])) { @@ -64,17 +67,17 @@ _elstr_syllabize(struct elstr *elstr) else if (elchr_isvowel(elstr->str[i])) sylmap[nsyl++] = i; dstate = nstate; } if (dstate) sylmap[nsyl++] = i - 1; - else + else if (nsyl) sylmap[nsyl-1] = i - 1; elstr->nsyl = nsyl; elstr->acc_pos = accchr; - elstr->acc_syl = nsyl - accsyl; + elstr->acc_syl = (accsyl >= 0) ? nsyl - accsyl : 0; } static SCM _elstr_alloc_empty(struct elstr **pelstr) { struct elstr *elstr; @@ -111,17 +114,20 @@ _elstr_dup(struct elstr *elstr) struct elstr *elnew; elnew = scm_gc_malloc(sizeof(*elstr), "Elstr"); elnew->str = calloc(elstr->len, sizeof(elnew->str[0])); if (!elnew->str) scm_memory_error("_elstr_dup"); - elnew->sylmap = calloc(elstr->nsyl, sizeof(elnew->sylmap[0])); - if (!elnew->sylmap) { - free(elnew->str); - scm_memory_error("_elstr_dup"); - } + if (elstr->sylmap) { + elnew->sylmap = calloc(elstr->nsyl, sizeof(elnew->sylmap[0])); + if (!elnew->sylmap) { + free(elnew->str); + scm_memory_error("_elstr_dup"); + } + } else + elnew->sylmap = NULL; memcpy(elnew->str, elstr->str, sizeof(elstr->str[0]) * elstr->len); elnew->len = elstr->len; elnew->nsyl = elstr->nsyl; memcpy(elnew->sylmap, elstr->sylmap, sizeof(elstr->sylmap[0]) * elstr->nsyl); elnew->acc_syl = elstr->acc_syl; @@ -148,13 +154,13 @@ _elstr_concat(struct elstr *dest, struct elstr *src, const char *func_name) static scm_sizet _elstr_free(SCM smob) { struct elstr *elstr = (struct elstr *) SCM_CDR(smob); free(elstr->str); free(elstr->sylmap); - free(elstr); + scm_gc_free(elstr, sizeof(struct elstr), "elstr"); return 0; } static int _elstr_print(SCM smob, SCM port, scm_print_state *pstate) { |