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 | |||
@@ -40,13 +40,16 @@ static void | |||
40 | _elstr_syllabize(struct elstr *elstr) | 40 | _elstr_syllabize(struct elstr *elstr) |
41 | { | 41 | { |
42 | unsigned *sylmap; | 42 | unsigned *sylmap; |
43 | unsigned i, nsyl = 0, accsyl = 0, accchr = 0; | 43 | unsigned i, nsyl = 0, accchr = 0; |
44 | int accsyl = -1; | ||
44 | int dstate = 0; | 45 | int dstate = 0; |
45 | int acc = 0; | 46 | int acc = 0; |
46 | 47 | ||
47 | if (!elstr->sylmap) | 48 | if (!elstr->sylmap) { |
48 | elstr->sylmap = scm_gc_malloc(sizeof(sylmap[0])*elstr->len, | 49 | elstr->sylmap = calloc(elstr->len, sizeof(sylmap[0])); |
49 | "syllable map"); | 50 | if (!elstr->sylmap) |
51 | scm_memory_error("_elstr_syllabize"); | ||
52 | } | ||
50 | sylmap = elstr->sylmap; | 53 | sylmap = elstr->sylmap; |
51 | 54 | ||
52 | for (i = 0; i < elstr->len; i++) { | 55 | for (i = 0; i < elstr->len; i++) { |
@@ -67,11 +70,11 @@ _elstr_syllabize(struct elstr *elstr) | |||
67 | } | 70 | } |
68 | if (dstate) | 71 | if (dstate) |
69 | sylmap[nsyl++] = i - 1; | 72 | sylmap[nsyl++] = i - 1; |
70 | else | 73 | else if (nsyl) |
71 | sylmap[nsyl-1] = i - 1; | 74 | sylmap[nsyl-1] = i - 1; |
72 | elstr->nsyl = nsyl; | 75 | elstr->nsyl = nsyl; |
73 | elstr->acc_pos = accchr; | 76 | elstr->acc_pos = accchr; |
74 | elstr->acc_syl = nsyl - accsyl; | 77 | elstr->acc_syl = (accsyl >= 0) ? nsyl - accsyl : 0; |
75 | } | 78 | } |
76 | 79 | ||
77 | static SCM | 80 | static SCM |
@@ -114,11 +117,14 @@ _elstr_dup(struct elstr *elstr) | |||
114 | elnew->str = calloc(elstr->len, sizeof(elnew->str[0])); | 117 | elnew->str = calloc(elstr->len, sizeof(elnew->str[0])); |
115 | if (!elnew->str) | 118 | if (!elnew->str) |
116 | scm_memory_error("_elstr_dup"); | 119 | scm_memory_error("_elstr_dup"); |
117 | elnew->sylmap = calloc(elstr->nsyl, sizeof(elnew->sylmap[0])); | 120 | if (elstr->sylmap) { |
118 | if (!elnew->sylmap) { | 121 | elnew->sylmap = calloc(elstr->nsyl, sizeof(elnew->sylmap[0])); |
119 | free(elnew->str); | 122 | if (!elnew->sylmap) { |
120 | scm_memory_error("_elstr_dup"); | 123 | free(elnew->str); |
121 | } | 124 | scm_memory_error("_elstr_dup"); |
125 | } | ||
126 | } else | ||
127 | elnew->sylmap = NULL; | ||
122 | memcpy(elnew->str, elstr->str, sizeof(elstr->str[0]) * elstr->len); | 128 | memcpy(elnew->str, elstr->str, sizeof(elstr->str[0]) * elstr->len); |
123 | elnew->len = elstr->len; | 129 | elnew->len = elstr->len; |
124 | elnew->nsyl = elstr->nsyl; | 130 | elnew->nsyl = elstr->nsyl; |
@@ -151,7 +157,7 @@ _elstr_free(SCM smob) | |||
151 | struct elstr *elstr = (struct elstr *) SCM_CDR(smob); | 157 | struct elstr *elstr = (struct elstr *) SCM_CDR(smob); |
152 | free(elstr->str); | 158 | free(elstr->str); |
153 | free(elstr->sylmap); | 159 | free(elstr->sylmap); |
154 | free(elstr); | 160 | scm_gc_free(elstr, sizeof(struct elstr), "elstr"); |
155 | return 0; | 161 | return 0; |
156 | } | 162 | } |
157 | 163 | ||