[PATCH 2/2] Support UTF8 encoded tags

Maximilian Güntner maximilian.guentner at gmail.com
Thu Nov 14 10:47:30 UTC 2013


UTF8 support was broken for tags.
Tags encoded in UTF8 were displayed
with a wrong encoding.

addresses bug #230

Signed-off-by: Maximilian Güntner <maximilian.guentner at gmail.com>
---
 parse-xml.c                | 53 ++++++++++++++++++++++++----------------------
 qt-ui/completionmodels.cpp |  2 +-
 qt-ui/maintab.cpp          |  7 +++---
 save-xml.c                 |  4 ++--
 4 files changed, 35 insertions(+), 31 deletions(-)

diff --git a/parse-xml.c b/parse-xml.c
index f582a30..07e828b 100644
--- a/parse-xml.c
+++ b/parse-xml.c
@@ -29,6 +29,23 @@ char *xslt_path;
 struct dive_table dive_table;
 struct dive_table *target_table = NULL;
 
+static void utf8_string(char *buffer, void *_res)
+{
+	int size;
+	char *res;
+	while (isspace(*buffer))
+		buffer++;
+	size = strlen(buffer);
+	while (size && isspace(buffer[size-1]))
+		size--;
+	if (!size)
+		return;
+	res = malloc(size + 1);
+	memcpy(res, buffer, size);
+	res[size] = 0;
+	*(char **)_res = res;
+}
+
 static void parser_error(char **error, const char *fmt, ...)
 {
 	va_list args;
@@ -218,19 +235,21 @@ enum ParseState {FINDSTART, FINDEND};
 static void divetags(char *buffer, void *_tags)
 {
 	struct tag_entry *tags = _tags;
+	char *utf8_buffer;
 	char tag[128];
 	int i = 0, start = 0, end = 0;
 	enum ParseState state = FINDEND;
+	utf8_string(buffer, &utf8_buffer);
 	i=0;
-	while(i < strlen(buffer)) {
-		if (buffer[i] == ',') {
+	while(i < strlen(utf8_buffer)) {
+		if (utf8_buffer[i] == ',') {
 			if (state == FINDSTART) {
 				/* Detect empty tags */
 			} else if (state == FINDEND) {
 				/* Found end of tag */
 				if (i > 1) {
-					if(buffer[i-1] != '\\') {
-						strncpy(tag, buffer+start, end-start+1);
+					if(utf8_buffer[i-1] != '\\') {
+						strncpy(tag, utf8_buffer+start, end-start+1);
 						tag[end-start+1] = '\0';
 						state=FINDSTART;
 						taglist_add_tag(tags, tag);
@@ -239,7 +258,7 @@ static void divetags(char *buffer, void *_tags)
 					state=FINDSTART;
 				}
 			}
-		} else if (buffer[i] == ' ') {
+		} else if (utf8_buffer[i] == ' ') {
 			/* Handled */
 		} else {
 			/* Found start of tag */
@@ -254,13 +273,14 @@ static void divetags(char *buffer, void *_tags)
     }
     if (state == FINDEND) {
 	    if (end < start)
-		    end = strlen(buffer)-1;
-	    if (strlen(buffer) > 0) {
-		    strncpy(tag, buffer+start, end-start+1);
+		    end = strlen(utf8_buffer)-1;
+	    if (strlen(utf8_buffer) > 0) {
+		    strncpy(tag, utf8_buffer+start, end-start+1);
 		    tag[end-start+1] = '\0';
 		    taglist_add_tag(tags, tag);
 	    }
     }
+    free(utf8_buffer);
 }
 
 enum number_type {
@@ -612,23 +632,6 @@ static void cylindersize(char *buffer, void *_volume)
 	}
 }
 
-static void utf8_string(char *buffer, void *_res)
-{
-	int size;
-	char *res;
-	while (isspace(*buffer))
-		buffer++;
-	size = strlen(buffer);
-	while (size && isspace(buffer[size-1]))
-		size--;
-	if (!size)
-		return;
-	res = malloc(size + 1);
-	memcpy(res, buffer, size);
-	res[size] = 0;
-	*(char **)_res = res;
-}
-
 #define MATCH(pattern, fn, dest) \
 	match(pattern, strlen(pattern), name, fn, buf, dest)
 
diff --git a/qt-ui/completionmodels.cpp b/qt-ui/completionmodels.cpp
index 31733ad..965ce87 100644
--- a/qt-ui/completionmodels.cpp
+++ b/qt-ui/completionmodels.cpp
@@ -43,7 +43,7 @@ void TagCompletionModel::updateModel()
 	QStringList list;
 	struct tag_entry *current_tag_entry = g_tag_list->next;
 	while (current_tag_entry != NULL) {
-		list.append(QString(current_tag_entry->tag->name));
+		list.append(QString::fromUtf8(current_tag_entry->tag->name));
 		current_tag_entry = current_tag_entry->next;
 	}
 	setStringList(list);
diff --git a/qt-ui/maintab.cpp b/qt-ui/maintab.cpp
index bd10ed3..7380c72 100644
--- a/qt-ui/maintab.cpp
+++ b/qt-ui/maintab.cpp
@@ -89,6 +89,7 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent),
 	completers.location = new QCompleter(LocationCompletionModel::instance(), ui.location);
 	completers.suit = new QCompleter(SuitCompletionModel::instance(), ui.suit);
 	completers.tags = new QCompleter(TagCompletionModel::instance(), ui.tagWidget);
+	completers.tags->setCaseSensitivity(Qt::CaseInsensitive);
 	ui.buddy->setCompleter(completers.buddy);
 	ui.divemaster->setCompleter(completers.divemaster);
 	ui.location->setCompleter(completers.location);
@@ -171,7 +172,7 @@ void MainTab::enableEdition(EditMode newEditMode)
 			notesBackup[mydive].datetime = QDateTime::fromTime_t(mydive->when - gettimezoneoffset()).toString(QString("M/d/yy h:mm"));
 			char buf[1024];
 			taglist_get_tagstring(mydive->tag_list, buf, 1024);
-			notesBackup[mydive].tags = QString(buf);
+			notesBackup[mydive].tags = QString::fromUtf8(buf);
 
 			// maybe this is a place for memset?
 			for (int i = 0; i < MAX_CYLINDERS; i++) {
@@ -393,7 +394,7 @@ void MainTab::updateDiveInfo(int dive)
 
 		char buf[1024];
 		taglist_get_tagstring(d->tag_list, buf, 1024);
-		ui.tagWidget->setText(QString(buf));
+		ui.tagWidget->setText(QString::fromUtf8(buf));
 
 		multiEditEquipmentPlaceholder = *d;
 		cylindersModel->setDive(&multiEditEquipmentPlaceholder);
@@ -695,7 +696,7 @@ void MainTab::saveTags()
 		QString tag;
 		taglist_clear(mydive->tag_list);
 		foreach (tag, ui.tagWidget->getBlockStringList())
-			taglist_add_tag(mydive->tag_list, tag.toAscii().data());
+			taglist_add_tag(mydive->tag_list, tag.toUtf8().data());
 	);
 }
 
diff --git a/save-xml.c b/save-xml.c
index 5b0ef42..d16b16d 100644
--- a/save-xml.c
+++ b/save-xml.c
@@ -406,9 +406,9 @@ static void save_tags(FILE *f, struct tag_entry *tag_list)
 				fprintf(f, ", ");
 			/* If the tag has been translated, write the source to the xml file */
 			if (tmp->tag->source != NULL)
-				fprintf(f, "%s", tmp->tag->source);
+				quote(f, tmp->tag->source, 0);
 			else
-				fprintf(f, "%s", tmp->tag->name);
+				quote(f, tmp->tag->name, 0);
 			tmp = tmp->next;
 			more = 1;
 		}
-- 
1.8.4.2



More information about the subsurface mailing list