transliteration: use double pointers on syllable chain
This commit is contained in:
parent
f2d74710d6
commit
9093211ae3
3 changed files with 21 additions and 41 deletions
18
syllable.c
18
syllable.c
|
@ -3,17 +3,18 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "syllable.h"
|
#include "syllable.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
|
|
||||||
struct syllable *syllable_alloc(const char *data)
|
struct syllable *syllable_alloc(const char *data, unsigned int code)
|
||||||
{
|
{
|
||||||
struct syllable *ptr = malloc(sizeof(*ptr));
|
struct syllable *ptr = malloc(sizeof(*ptr));
|
||||||
|
|
||||||
if (ptr == NULL)
|
if (ptr == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
ptr->data = strdup(data);
|
ptr->data = data != NULL ? strdup(data) : utf8_code_to_string(code);
|
||||||
ptr->code = 0;
|
ptr->code = code;
|
||||||
ptr->prev = NULL;
|
ptr->prev = NULL;
|
||||||
ptr->next = NULL;
|
ptr->next = NULL;
|
||||||
|
|
||||||
|
@ -30,17 +31,6 @@ void syllable_drop(struct syllable *ptr)
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct syllable *syllable_append(struct syllable *tail, const char *data)
|
|
||||||
{
|
|
||||||
struct syllable *ptr;
|
|
||||||
|
|
||||||
ptr = syllable_alloc(data);
|
|
||||||
ptr->prev = tail;
|
|
||||||
tail->next = ptr;
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int syllable_chain_length(struct syllable *head)
|
unsigned int syllable_chain_length(struct syllable *head)
|
||||||
{
|
{
|
||||||
struct syllable *walk = head;
|
struct syllable *walk = head;
|
||||||
|
|
|
@ -10,11 +10,9 @@ struct syllable {
|
||||||
struct syllable *next;
|
struct syllable *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct syllable *syllable_alloc();
|
struct syllable *syllable_alloc(const char *data, unsigned int code);
|
||||||
void syllable_drop(struct syllable *syllable);
|
void syllable_drop(struct syllable *syllable);
|
||||||
|
|
||||||
struct syllable *syllable_append(struct syllable *tail, const char *data);
|
|
||||||
|
|
||||||
unsigned int syllable_chain_length(struct syllable *head);
|
unsigned int syllable_chain_length(struct syllable *head);
|
||||||
char *syllable_chain_to_string(struct syllable *head);
|
char *syllable_chain_to_string(struct syllable *head);
|
||||||
void syllable_chain_drop(struct syllable *head);
|
void syllable_chain_drop(struct syllable *head);
|
||||||
|
|
|
@ -28,6 +28,9 @@ static void syllable_modify(struct syllable *syllable, const char *data)
|
||||||
{
|
{
|
||||||
char buffer[10];
|
char buffer[10];
|
||||||
|
|
||||||
|
if (syllable == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
strcpy(buffer, syllable->data);
|
strcpy(buffer, syllable->data);
|
||||||
buffer[strlen(buffer) - 1] = 0;
|
buffer[strlen(buffer) - 1] = 0;
|
||||||
strcat(buffer, data);
|
strcat(buffer, data);
|
||||||
|
@ -47,46 +50,35 @@ static void apply_transliteration_filters(struct syllable *head,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
char *transliterate_devanagari_to_latin(const char *text,
|
char *transliterate_devanagari_to_latin(const char *devanagari,
|
||||||
const struct transliteration_context *context)
|
const struct transliteration_context *context)
|
||||||
{
|
{
|
||||||
unsigned int length = strlen(text);
|
struct syllable *head = NULL, *tail = NULL, **indirect = &head;
|
||||||
const char *ptr = text;
|
|
||||||
const char *end = ptr + length;
|
|
||||||
char *tmp;
|
|
||||||
unsigned int code;
|
|
||||||
struct syllable *head, *tail;
|
|
||||||
const struct transliteration_letter *letter;
|
const struct transliteration_letter *letter;
|
||||||
|
const char *ptr = devanagari;
|
||||||
head = syllable_alloc("");
|
const char *end = ptr + strlen(devanagari);
|
||||||
tail = head;
|
unsigned int code;
|
||||||
|
char *retval;
|
||||||
|
|
||||||
while (ptr < end) {
|
while (ptr < end) {
|
||||||
code = utf8_unpack_char(ptr);
|
code = utf8_unpack_char(ptr);
|
||||||
ptr += utf8_char_length(code);
|
ptr += utf8_char_length(code);
|
||||||
|
|
||||||
letter = find_letter_by_code(code, context->table);
|
letter = find_letter_by_code(code, context->table);
|
||||||
if (letter != NULL) {
|
if (letter && letter->flags & FLAG_MODIFIER) {
|
||||||
|
syllable_modify(tail, letter->data);
|
||||||
if (letter->flags & FLAG_REGULAR) {
|
|
||||||
tail = syllable_append(tail, letter->data);
|
|
||||||
tail->code = code;
|
|
||||||
} else if (letter->flags & FLAG_MODIFIER) {
|
|
||||||
syllable_modify(tail, letter->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp = utf8_code_to_string(code);
|
*indirect = syllable_alloc(letter ? letter->data : NULL, code);
|
||||||
tail = syllable_append(tail, tmp);
|
tail = *indirect;
|
||||||
free(tmp);
|
indirect = &(*indirect)->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
apply_transliteration_filters(head, context->filters);
|
apply_transliteration_filters(head, context->filters);
|
||||||
|
|
||||||
tmp = syllable_chain_to_string(head);
|
retval = syllable_chain_to_string(head);
|
||||||
syllable_chain_drop(head);
|
syllable_chain_drop(head);
|
||||||
|
|
||||||
return tmp;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue