Merge "Fix to check whether it is possible to access to files" into tizen
[platform/core/uifw/tts.git] / common / tts_config_parser.c
1 /*
2 *  Copyright (c) 2011-2016 Samsung Electronics Co., Ltd All Rights Reserved 
3 *  Licensed under the Apache License, Version 2.0 (the "License");
4 *  you may not use this file except in compliance with the License.
5 *  You may obtain a copy of the License at
6 *  http://www.apache.org/licenses/LICENSE-2.0
7 *  Unless required by applicable law or agreed to in writing, software
8 *  distributed under the License is distributed on an "AS IS" BASIS,
9 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
10 *  See the License for the specific language governing permissions and
11 *  limitations under the License.
12 */
13
14 #include <dlog.h>
15 #include <stdio.h>
16 #include <sys/stat.h>
17 #include <unistd.h>
18 #include <vconf.h>
19
20 #include "tts_config_parser.h"
21 #include "tts_defs.h"
22
23
24 #define TTS_TAG_ENGINE_BASE_TAG         "tts-engine"
25 #define TTS_TAG_ENGINE_NAME             "name"
26 #define TTS_TAG_ENGINE_ID               "id"
27 #define TTS_TAG_ENGINE_SETTING          "setting"
28 #define TTS_TAG_ENGINE_VOICE_SET        "voices"
29 #define TTS_TAG_ENGINE_VOICE            "voice"
30 #define TTS_TAG_ENGINE_VOICE_TYPE       "type"
31 #define TTS_TAG_ENGINE_PITCH_SUPPORT    "pitch-support"
32 #define TTS_TAG_ENGINE_TEXT_SIZE        "text-size"
33
34 #define TTS_TAG_CONFIG_BASE_TAG         "tts-config"
35 #define TTS_TAG_CONFIG_ENGINE_ID        "engine"
36 #define TTS_TAG_CONFIG_ENGINE_SETTING   "engine-setting"
37 #define TTS_TAG_CONFIG_AUTO_VOICE       "auto"
38 #define TTS_TAG_CONFIG_VOICE_TYPE       "voice-type"
39 #define TTS_TAG_CONFIG_LANGUAGE         "language"
40 #define TTS_TAG_CONFIG_SPEECH_RATE      "speech-rate"
41 #define TTS_TAG_CONFIG_PITCH            "pitch"
42 #define TTS_TAG_VOICE_TYPE_FEMALE       "female"
43 #define TTS_TAG_VOICE_TYPE_MALE         "male"
44 #define TTS_TAG_VOICE_TYPE_CHILD        "child"
45
46 #define TTS_MAX_TEXT_SIZE       2000
47
48 extern char* tts_tag();
49
50 static xmlDocPtr g_config_doc = NULL;
51 char g_engine_id[128] = {0,};
52 char g_setting[128] = {0,};
53 char g_language[128] = {0,};
54
55 int tts_parser_get_engine_info(const char* path, tts_engine_info_s** engine_info)
56 {
57         if (NULL == path || NULL == engine_info) {
58                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
59                 return -1;
60         }
61
62         bool isTextsize = false;
63         xmlDocPtr doc = NULL;
64         xmlNodePtr cur = NULL;
65         xmlChar *key = NULL;
66         xmlChar *attr = NULL;
67
68         if (0 == access(path, F_OK)) {
69                 SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Success to access to %s", path);
70                 doc = xmlParseFile(path);
71                 if (doc == NULL) {
72                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse xml file");
73                         return -1;
74                 }
75         } else {
76                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to access to %s", path);
77                 return -1;
78         }
79
80         cur = xmlDocGetRootElement(doc);
81         if (cur == NULL) {
82                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
83                 xmlFreeDoc(doc);
84                 doc = NULL;
85                 return -1;
86         }
87
88         if (xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_BASE_TAG)) {
89                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT 'tts-engine'");
90                 xmlFreeDoc(doc);
91                 doc = NULL;
92                 return -1;
93         }
94
95         cur = cur->xmlChildrenNode;
96         if (cur == NULL) {
97                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
98                 xmlFreeDoc(doc);
99                 doc = NULL;
100                 return -1;
101         }
102
103         /* alloc engine info */
104         tts_engine_info_s* temp;
105         temp = (tts_engine_info_s*)calloc(1, sizeof(tts_engine_info_s));
106         if (NULL == temp) {
107                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Out of memory");
108                 xmlFreeDoc(doc);
109                 doc = NULL;
110                 return -1;
111         }
112
113         temp->name = NULL;
114         temp->uuid = NULL;
115         temp->voices = NULL;
116         temp->setting = NULL;
117         temp->pitch_support = false;
118         temp->text_size = 0;
119
120         while (cur != NULL) {
121                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_NAME)) {
122                         key = xmlNodeGetContent(cur);
123                         if (NULL != key) {
124                                 if (NULL != temp->name) {
125                                         free(temp->name);
126                                         temp->name = NULL;
127                                 }
128                                 temp->name = strdup((char*)key);
129                                 xmlFree(key);
130                                 key = NULL;
131                         } else {
132                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_NAME);
133                         }
134                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_ID)) {
135                         key = xmlNodeGetContent(cur);
136                         if (NULL != key) {
137                                 if (NULL != temp->uuid) {
138                                         free(temp->uuid);
139                                         temp->uuid = NULL;
140                                 }
141                                 temp->uuid = strdup((char*)key);
142                                 xmlFree(key);
143                                 key = NULL;
144                         } else {
145                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_ID);
146                         }
147                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_SETTING)) {
148                         key = xmlNodeGetContent(cur);
149                         if (NULL != key) {
150                                 if (NULL != temp->setting) {
151                                         free(temp->setting);
152                                         temp->setting = NULL;
153                                 }
154                                 temp->setting = strdup((char*)key);
155                                 xmlFree(key);
156                                 key = NULL;
157                         } else {
158                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_SETTING);
159                         }
160                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE_SET)) {
161                         xmlNodePtr voice_node = NULL;
162                         voice_node = cur->xmlChildrenNode;
163
164                         while (NULL != voice_node) {
165                                 if (0 == xmlStrcmp(voice_node->name, (const xmlChar *)TTS_TAG_ENGINE_VOICE)) {
166                                         tts_config_voice_s* temp_voice = (tts_config_voice_s*)calloc(1, sizeof(tts_config_voice_s));
167                                         if (NULL == temp_voice) {
168                                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Out of memory");
169                                                 break;
170                                         }
171
172                                         attr = xmlGetProp(voice_node, (const xmlChar*)TTS_TAG_ENGINE_VOICE_TYPE);
173                                         if (NULL != attr) {
174                                                 if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
175                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
176                                                 } else if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
177                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
178                                                 } else if (0 == xmlStrcmp(attr, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
179                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
180                                                 } else {
181                                                         temp_voice->type = (int)TTS_CONFIG_VOICE_TYPE_USER_DEFINED;
182                                                 }
183                                                 xmlFree(attr);
184                                                 attr = NULL;
185                                         } else {
186                                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_VOICE_TYPE);
187                                                 free(temp_voice);
188                                                 temp_voice = NULL;
189                                                 continue;
190                                         }
191
192                                         key = xmlNodeGetContent(voice_node);
193                                         if (NULL != key) {
194                                                 if (NULL != temp_voice->language) {
195                                                         free(temp_voice->language);
196                                                         temp_voice->language = NULL;
197                                                 }
198                                                 temp_voice->language = strdup((char*)key);
199                                                 xmlFree(key);
200                                                 key = NULL;
201                                                 temp->voices = g_slist_append(temp->voices, temp_voice);
202                                         } else {
203                                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_VOICE);
204                                                 if (NULL != temp_voice) {
205                                                         free(temp_voice);
206                                                         temp_voice = NULL;
207                                                 }
208                                         }
209                                 }
210                                 voice_node = voice_node->next;
211                         }
212                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_PITCH_SUPPORT)) {
213                         key = xmlNodeGetContent(cur);
214                         if (NULL != key) {
215                                 if (0 == xmlStrcmp(key, (const xmlChar *)"true")) {
216                                         temp->pitch_support = true;
217                                 }
218                                 xmlFree(key);
219                                 key = NULL;
220                         } else {
221                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] <%s> has no content", TTS_TAG_ENGINE_PITCH_SUPPORT);
222                         }
223                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_ENGINE_TEXT_SIZE)) {
224                         isTextsize = true;
225                         key = xmlNodeGetContent(cur);
226                         if (NULL != key) {
227                                 temp->text_size = atoi((char*)key);
228                                 xmlFree(key);
229                         } else {
230                                 SLOG(LOG_INFO, tts_tag(), "[INFO] text size is unlimited.");
231                                 temp->text_size = 0;
232                         }
233                 }
234                 cur = cur->next;
235         }
236
237         if (false == isTextsize) {
238                 temp->text_size = TTS_MAX_TEXT_SIZE;
239         }
240
241         xmlFreeDoc(doc);
242         doc = NULL;
243
244         if (NULL == temp->uuid) {
245                 /* Invalid engine */
246                 SECURE_SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid engine : %s", path);
247                 tts_parser_free_engine_info(temp);
248                 return -1;
249         }
250
251         *engine_info = temp;
252
253         return 0;
254 }
255
256 int tts_parser_free_engine_info(tts_engine_info_s* engine_info)
257 {
258         if (NULL == engine_info) {
259                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
260                 return -1;
261         }
262
263         if (NULL != engine_info->name) {
264                 free(engine_info->name);
265                 engine_info->name = NULL;
266         }
267         if (NULL != engine_info->uuid) {
268                 free(engine_info->uuid);
269                 engine_info->uuid = NULL;
270         }
271         if (NULL != engine_info->setting) {
272                 free(engine_info->setting);
273                 engine_info->setting = NULL;
274         }
275
276         tts_config_voice_s *temp_voice;
277         temp_voice = g_slist_nth_data(engine_info->voices, 0);
278
279         while (NULL != temp_voice) {
280                 if (NULL != temp_voice) {
281                         if (NULL != temp_voice->language) {
282                                 free(temp_voice->language);
283                                 temp_voice->language = NULL;
284                         }
285                         engine_info->voices = g_slist_remove(engine_info->voices, temp_voice);
286                         free(temp_voice);
287                         temp_voice = NULL;
288                 }
289
290                 temp_voice = g_slist_nth_data(engine_info->voices, 0);
291         }
292
293         if (NULL != engine_info) {
294                 free(engine_info);
295                 engine_info = NULL;
296         }
297
298         return 0;
299 }
300
301 int tts_parser_print_engine_info(tts_engine_info_s* engine_info)
302 {
303         if (NULL == engine_info) {
304                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
305                 return -1;
306         }
307
308         SLOG(LOG_DEBUG, tts_tag(), "== get engine info ==");
309         SLOG(LOG_DEBUG, tts_tag(), " name : %s", engine_info->name);
310         SLOG(LOG_DEBUG, tts_tag(), " id   : %s", engine_info->uuid);
311         if (NULL != engine_info->setting)
312                 SLOG(LOG_DEBUG, tts_tag(), " setting : %s", engine_info->setting);
313
314         SLOG(LOG_DEBUG, tts_tag(), " voices");
315         GSList *iter = NULL;
316         tts_config_voice_s *temp_voice;
317
318         if (g_slist_length(engine_info->voices) > 0) {
319                 /* Get a first item */
320                 iter = g_slist_nth(engine_info->voices, 0);
321
322                 int i = 1;
323                 while (NULL != iter) {
324                         /*Get handle data from list*/
325                         temp_voice = iter->data;
326
327                         SLOG(LOG_DEBUG, tts_tag(), "  [%dth] type(%d) lang(%s)", 
328                                 i, temp_voice->type, temp_voice->language);
329
330                         /*Get next item*/
331                         iter = g_slist_next(iter);
332                         i++;
333                 }
334         } else {
335                 SLOG(LOG_ERROR, tts_tag(), "  Voice is NONE");
336         }
337
338         SLOG(LOG_DEBUG, tts_tag(), "@@@");
339
340         return 0;
341 }
342
343 int tts_parser_load_config(tts_config_s** config_info)
344 {
345         if (NULL == config_info) {
346                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
347                 return -1;
348         }
349
350         xmlDocPtr doc = NULL;
351         xmlNodePtr cur = NULL;
352         xmlChar *key;
353         bool is_default_open = false;
354
355         /* For Thread safety */
356         xmlInitParser();
357
358         if (0 != access(TTS_CONFIG, F_OK)) {
359                 doc = xmlParseFile(TTS_DEFAULT_CONFIG);
360                 if (doc == NULL) {
361                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", TTS_DEFAULT_CONFIG);
362                         xmlCleanupParser();
363                         return -1;
364                 }
365                 is_default_open = true;
366         } else {
367                 int retry_count = 0;
368
369                 while (NULL == doc) {
370                         doc = xmlParseFile(TTS_CONFIG);
371                         if (NULL != doc) {
372                                 break;
373                         }
374                         retry_count++;
375                         usleep(10000);
376
377                         if (TTS_RETRY_COUNT == retry_count) {
378                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", TTS_CONFIG);
379                                 doc = xmlParseFile(TTS_DEFAULT_CONFIG);
380                                 if (NULL == doc) {
381                                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", TTS_DEFAULT_CONFIG);
382                                         xmlCleanupParser();
383                                         return -1;
384                                 }
385                                 is_default_open = true;
386                                 break;
387                         }
388                 }
389         }
390
391         cur = xmlDocGetRootElement(doc);
392         if (cur == NULL) {
393                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
394                 xmlFreeDoc(doc);
395                 doc = NULL;
396                 xmlCleanupParser();
397                 return -1;
398         }
399
400         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
401                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
402                 xmlFreeDoc(doc);
403                 doc = NULL;
404                 xmlCleanupParser();
405                 return -1;
406         }
407
408         cur = cur->xmlChildrenNode;
409         if (cur == NULL) {
410                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
411                 xmlFreeDoc(doc);
412                 doc = NULL;
413                 xmlCleanupParser();
414                 return -1;
415         }
416
417         /* alloc engine info */
418         tts_config_s* temp;
419         temp = (tts_config_s*)calloc(1, sizeof(tts_config_s));
420         if (NULL == temp) {
421                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Out of memory");
422                 xmlFreeDoc(doc);
423                 doc = NULL;
424                 xmlCleanupParser();
425                 return -1;
426         }
427
428         memset(g_engine_id, '\0', sizeof(g_engine_id));
429         memset(g_setting, '\0', sizeof(g_setting));
430         memset(g_language, '\0', sizeof(g_language));
431
432         temp->engine_id = g_engine_id;
433         temp->setting = g_setting;
434         temp->language = g_language;
435
436         while (cur != NULL) {
437                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_ID)) {
438                         key = xmlNodeGetContent(cur);
439                         if (NULL != key) {
440                                 strncpy(temp->engine_id, (char*)key, sizeof(g_engine_id) - 1);
441                                 xmlFree(key);
442                                 key = NULL;
443                         } else {
444                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] engine id is NULL");
445                         }
446                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_SETTING)) {
447                         key = xmlNodeGetContent(cur);
448                         if (NULL != key) {
449                                 strncpy(temp->setting, (char*)key, sizeof(g_setting) - 1);
450                                 xmlFree(key);
451                                 key = NULL;
452                         } else {
453                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] setting path is NULL");
454                         }
455                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_AUTO_VOICE)) {
456                         key = xmlNodeGetContent(cur);
457                         if (NULL != key) {
458                                 if (0 == xmlStrcmp(key, (const xmlChar *)"on")) {
459                                         temp->auto_voice = true;
460                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)"off")) {
461                                         temp->auto_voice = false;
462                                 } else {
463                                         SLOG(LOG_ERROR, tts_tag(), "Auto voice is wrong");
464                                         temp->auto_voice = true;
465                                 }
466
467                                 xmlFree(key);
468                                 key = NULL;
469                         } else {
470                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] voice type is NULL");
471                         }
472                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_VOICE_TYPE)) {
473                         key = xmlNodeGetContent(cur);
474                         if (NULL != key) {
475                                 if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
476                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
477                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
478                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
479                                 } else if (0 == xmlStrcmp(key, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
480                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
481                                 } else {
482                                         SLOG(LOG_WARN, tts_tag(), "Voice type is user defined");
483                                         temp->type = (int)TTS_CONFIG_VOICE_TYPE_USER_DEFINED;
484                                 }
485
486                                 xmlFree(key);
487                                 key = NULL;
488                         } else {
489                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] voice type is NULL");
490                         }
491                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_LANGUAGE)) {
492                         key = xmlNodeGetContent(cur);
493                         if (NULL != key) {
494                                 strncpy(temp->language, (char*)key, sizeof(g_language) - 1);
495                                 xmlFree(key);
496                                 key = NULL;
497                         } else {
498                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] engine uuid is NULL");
499                         }
500
501                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_SPEECH_RATE)) {
502                         key = xmlNodeGetContent(cur);
503                         if (NULL != key) {
504                                 temp->speech_rate = atoi((char*)key);
505                                 xmlFree(key);
506                         } else {
507                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] speech rate is NULL");
508                         }
509                 } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_PITCH)) {
510                         key = xmlNodeGetContent(cur);
511                         if (NULL != key) {
512                                 temp->pitch = atoi((char*)key);
513                                 xmlFree(key);
514                                 key = NULL;
515                         } else {
516                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Pitch is NULL");
517                         }
518                 } else {
519
520                 }
521
522                 cur = cur->next;
523         }
524
525         *config_info = temp;
526         g_config_doc = doc;
527
528         if (true == is_default_open) {
529                 int retry_count = 0;
530                 int ret = -1;
531                 do {
532                         ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
533                         if (0 < ret)
534                                 break;
535                         retry_count++;
536                         usleep(10000);
537
538                         if (TTS_RETRY_COUNT == retry_count) {
539                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
540                                 return -1;
541                         }
542                 } while (0 != ret);
543
544                 /* Set mode */
545                 if (0 > chmod(TTS_CONFIG, 0600)) {
546                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to change file mode : %d", ret);
547                 }
548
549                 /* Set owner */
550                 if (0 > chown(TTS_CONFIG, 5000, 5000)) {
551                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to change file owner : %d", ret);
552                 }
553                 SLOG(LOG_DEBUG, tts_tag(), "Default config is changed : pid(%d)", getpid());
554         }
555
556         return 0;
557 }
558
559 int tts_parser_unload_config(tts_config_s* config_info)
560 {
561         if (NULL != g_config_doc) {
562                 xmlFreeDoc(g_config_doc);
563                 g_config_doc = NULL;
564         }
565         if (NULL != config_info) {
566                 free(config_info);
567                 config_info = NULL;
568         }
569
570         xmlCleanupParser();
571
572         return 0;
573 }
574
575
576 int tts_parser_copy_xml(const char* original, const char* destination)
577 {
578         if (NULL == original || NULL == destination) {
579                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
580                 return -1;
581         }
582
583         xmlDocPtr doc = NULL;
584         if (0 == access(original, F_OK)) {
585                 SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Success to access to %s", original);
586                 doc = xmlParseFile(original);
587                 if (doc == NULL) {
588                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", original);
589                         return -1;
590                 }
591         } else {
592                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to access to %s", original);
593                 return -1;
594         }
595
596         int ret = xmlSaveFile(destination, doc);
597         if (0 > ret) {
598                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
599         } else {
600                 SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Success to save %s", destination);
601         }
602
603         /* Set mode */
604         if (0 > chmod(destination, 0600)) {
605                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to change file mode : %d", ret);
606         }
607
608         xmlFreeDoc(doc);
609         doc = NULL;
610         SLOG(LOG_DEBUG, tts_tag(), "[SUCCESS] Copying xml");
611
612         return 0;
613 }
614
615 int tts_parser_set_engine(const char* engine_id, const char* setting, const char* language, int type)
616 {
617         if (NULL == engine_id) {
618                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
619                 return -1;
620         }
621
622         xmlNodePtr cur = NULL;
623         cur = xmlDocGetRootElement(g_config_doc);
624         if (cur == NULL) {
625                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
626                 return -1;
627         }
628
629         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
630                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
631                 return -1;
632         }
633
634         cur = cur->xmlChildrenNode;
635         if (cur == NULL) {
636                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
637                 return -1;
638         }
639
640         while (cur != NULL) {
641                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_ID)) {
642                         xmlNodeSetContent(cur, (const xmlChar *)engine_id);
643                 }
644
645                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_LANGUAGE)) {
646                         xmlNodeSetContent(cur, (const xmlChar *)language);
647                 }
648
649                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_ENGINE_SETTING)) {
650                         xmlNodeSetContent(cur, (const xmlChar *)setting);
651                 }
652
653                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_VOICE_TYPE)) {
654                         switch (type) {
655                         case TTS_CONFIG_VOICE_TYPE_MALE:        xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_MALE);        break;
656                         case TTS_CONFIG_VOICE_TYPE_FEMALE:      xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_FEMALE);      break;
657                         case TTS_CONFIG_VOICE_TYPE_CHILD:       xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_CHILD);       break;
658                         default:                                xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_FEMALE);      break;
659                         }
660                 }
661
662                 cur = cur->next;
663         }
664
665         int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
666         if (0 > ret) {
667                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
668         } else {
669                 SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Success to save %s", TTS_CONFIG);
670         }
671
672         return 0;
673 }
674
675 int tts_parser_set_voice(const char* language, int type)
676 {
677         if (NULL == language) {
678                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
679                 return -1;
680         }
681
682         xmlNodePtr cur = NULL;
683         cur = xmlDocGetRootElement(g_config_doc);
684         if (cur == NULL) {
685                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
686                 return -1;
687         }
688
689         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
690                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
691                 return -1;
692         }
693
694         cur = cur->xmlChildrenNode;
695         if (cur == NULL) {
696                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
697                 return -1;
698         }
699
700         while (cur != NULL) {
701                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_LANGUAGE)) {
702                         xmlNodeSetContent(cur, (const xmlChar *)language);
703                 }
704
705                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_VOICE_TYPE)) {
706                         switch (type) {
707                         case TTS_CONFIG_VOICE_TYPE_MALE:        xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_MALE);        break;
708                         case TTS_CONFIG_VOICE_TYPE_FEMALE:      xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_FEMALE);      break;
709                         case TTS_CONFIG_VOICE_TYPE_CHILD:       xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_CHILD);       break;
710                         default:
711                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Invalid type : %d", type);
712                                 xmlNodeSetContent(cur, (const xmlChar*)TTS_TAG_VOICE_TYPE_FEMALE);
713                                 break;
714                         }
715                 }
716
717                 cur = cur->next;
718         }
719
720         int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
721         if (0 > ret) {
722                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
723         } else {
724                 SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Success to save %s", TTS_CONFIG);
725         }
726
727         return 0;
728 }
729
730 int tts_parser_set_auto_voice(bool value)
731 {
732         xmlNodePtr cur = NULL;
733         cur = xmlDocGetRootElement(g_config_doc);
734         if (cur == NULL) {
735                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
736                 return -1;
737         }
738
739         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
740                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
741                 return -1;
742         }
743
744         cur = cur->xmlChildrenNode;
745         if (cur == NULL) {
746                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
747                 return -1;
748         }
749
750         while (cur != NULL) {
751                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_AUTO_VOICE)) {
752                         if (true == value) {
753                                 xmlNodeSetContent(cur, (const xmlChar *)"on");
754                         } else if (false == value) {
755                                 xmlNodeSetContent(cur, (const xmlChar *)"off");
756                         } else {
757                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong value of auto voice");
758                                 return -1;
759                         }
760                         break;
761                 }
762                 cur = cur->next;
763         }
764
765         int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
766         if (0 > ret) {
767                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
768         } else {
769                 SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Success to save %s", TTS_CONFIG);
770         }
771
772         return 0;
773 }
774
775 int tts_parser_set_speech_rate(int value)
776 {
777         xmlNodePtr cur = NULL;
778         cur = xmlDocGetRootElement(g_config_doc);
779         if (cur == NULL) {
780                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
781                 return -1;
782         }
783
784         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
785                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
786                 return -1;
787         }
788
789         cur = cur->xmlChildrenNode;
790         if (cur == NULL) {
791                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
792                 return -1;
793         }
794
795         while (cur != NULL) {
796                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_SPEECH_RATE)) {
797                         char temp[10];
798                         memset(temp, '\0', 10);
799                         snprintf(temp, 10, "%d", value);
800
801                         xmlNodeSetContent(cur, (const xmlChar *)temp);
802
803                         SLOG(LOG_DEBUG, tts_tag(), "Set speech rate : %s", temp);
804                         break;
805                 }
806
807                 cur = cur->next;
808         }
809
810         int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
811         if (0 > ret) {
812                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
813         } else {
814                 SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Success to save %s", TTS_CONFIG);
815         }
816
817         return 0;
818 }
819
820 int tts_parser_set_pitch(int value)
821 {
822         xmlNodePtr cur = NULL;
823         cur = xmlDocGetRootElement(g_config_doc);
824         if (cur == NULL) {
825                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
826                 return -1;
827         }
828
829         if (xmlStrcmp(cur->name, (const xmlChar *) TTS_TAG_CONFIG_BASE_TAG)) {
830                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
831                 return -1;
832         }
833
834         cur = cur->xmlChildrenNode;
835         if (cur == NULL) {
836                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
837                 return -1;
838         }
839
840         while (cur != NULL) {
841                 if (0 == xmlStrcmp(cur->name, (const xmlChar *)TTS_TAG_CONFIG_PITCH)) {
842                         char temp[10];
843                         memset(temp, '\0', 10);
844                         snprintf(temp, 10, "%d", value);
845                         xmlNodeSetContent(cur, (const xmlChar *)temp);
846                         break;
847                 }
848
849                 cur = cur->next;
850         }
851
852         int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
853         if (0 > ret) {
854                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Save result : %d", ret);
855         } else {
856                 SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Success to save %s", TTS_CONFIG);
857         }
858
859         return 0;
860 }
861
862 int tts_parser_find_config_changed(char** engine, char**setting, bool* auto_voice, char** language, int* voice_type, 
863                                    int* speech_rate, int* pitch)
864 {
865         if (NULL == engine || NULL == setting || NULL == language || NULL == voice_type || NULL == speech_rate) {
866                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Input parameter is NULL");
867                 return -1;
868         }
869
870         xmlDocPtr doc = NULL;
871         xmlNodePtr cur_new = NULL;
872         xmlNodePtr cur_old = NULL;
873
874         xmlChar *key_new;
875         xmlChar *key_old;
876
877         int retry_count = 0;
878         while (NULL == doc) {
879                 if (0 == access(TTS_CONFIG, F_OK)) {
880                         SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Success to access to %s", TTS_CONFIG);
881                         doc = xmlParseFile(TTS_CONFIG);
882                         if (NULL != doc) {
883                                 break;
884                         }
885                 }
886                 retry_count++;
887                 usleep(10000);
888
889                 if (TTS_RETRY_COUNT == retry_count) {
890                         SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse file error : %s", TTS_CONFIG);
891                         return -1;
892                 }
893         }
894
895         cur_new = xmlDocGetRootElement(doc);
896         cur_old = xmlDocGetRootElement(g_config_doc);
897         if (cur_new == NULL || cur_old == NULL) {
898                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
899                 xmlFreeDoc(doc);
900                 doc = NULL;
901                 return -1;
902         }
903
904         if (xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_BASE_TAG) || 
905         xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_BASE_TAG)) {
906                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] The wrong type, root node is NOT %s", TTS_TAG_CONFIG_BASE_TAG);
907                 xmlFreeDoc(doc);
908                 doc = NULL;
909                 return -1;
910         }
911
912         cur_new = cur_new->xmlChildrenNode;
913         cur_old = cur_old->xmlChildrenNode;
914         if (cur_new == NULL || cur_old == NULL) {
915                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Empty document");
916                 xmlFreeDoc(doc);
917                 doc = NULL;
918                 return -1;
919         }
920
921         while (cur_new != NULL && cur_old != NULL) {
922                 if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_ID)) {
923                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_ID)) {
924                                 key_old = xmlNodeGetContent(cur_old);
925                                 if (NULL != key_old) {
926                                         key_new = xmlNodeGetContent(cur_new);
927                                         if (NULL != key_new) {
928                                                 if (0 != xmlStrcmp(key_old, key_new)) {
929                                                         SLOG(LOG_DEBUG, tts_tag(), "Old engine id(%s), New engine(%s)", 
930                                                                 (char*)key_old, (char*)key_new);
931                                                         if (NULL != *engine) {
932                                                                 free(*engine);
933                                                                 *engine = NULL;
934                                                         }
935                                                         *engine = strdup((char*)key_new);
936                                                 }
937                                                 xmlFree(key_new);
938                                                 key_new = NULL;
939                                         }
940                                         xmlFree(key_old);
941                                         key_old = NULL;
942                                 }
943                         } else {
944                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
945                         }
946                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_SETTING)) {
947                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_ENGINE_SETTING)) {
948                                 key_old = xmlNodeGetContent(cur_old);
949                                 if (NULL != key_old) {
950                                         key_new = xmlNodeGetContent(cur_new);
951                                         if (NULL != key_new) {
952                                                 if (0 != xmlStrcmp(key_old, key_new)) {
953                                                         SLOG(LOG_DEBUG, tts_tag(), "Old engine setting(%s), New engine setting(%s)", 
954                                                                 (char*)key_old, (char*)key_new);
955                                                         if (NULL != *setting) {
956                                                                 free(*setting);
957                                                                 *setting = NULL;
958                                                         }
959                                                         *setting = strdup((char*)key_new);
960                                                 }
961                                                 xmlFree(key_new);
962                                                 key_new = NULL;
963                                         }
964                                         xmlFree(key_old);
965                                         key_old = NULL;
966                                 }
967                         } else {
968                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
969                         }
970                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_AUTO_VOICE)) {
971                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_AUTO_VOICE)) {
972                                 key_old = xmlNodeGetContent(cur_old);
973                                 if (NULL != key_old) {
974                                         key_new = xmlNodeGetContent(cur_new);
975                                         if (NULL != key_new) {
976                                                 if (0 != xmlStrcmp(key_old, key_new)) {
977                                                         SLOG(LOG_DEBUG, tts_tag(), "Old auto voice (%s), New auto voice(%s)", 
978                                                                 (char*)key_old, (char*)key_new);
979                                                         if (0 == xmlStrcmp((const xmlChar*)"on", key_new)) {
980                                                                 *auto_voice = true;
981                                                         } else {
982                                                                 *auto_voice = false;
983                                                         }
984                                                 }
985                                                 xmlFree(key_new);
986                                                 key_new = NULL;
987                                         }
988                                         xmlFree(key_old);
989                                         key_old = NULL;
990                                 }
991                         } else {
992                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
993                         }
994                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_LANGUAGE)) {
995                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_LANGUAGE)) {
996                                 key_old = xmlNodeGetContent(cur_old);
997                                 if (NULL != key_old) {
998                                         key_new = xmlNodeGetContent(cur_new);
999                                         if (NULL != key_new) {
1000                                                 if (0 != xmlStrcmp(key_old, key_new)) {
1001                                                         SLOG(LOG_DEBUG, tts_tag(), "Old language(%s), New language(%s)", 
1002                                                                 (char*)key_old, (char*)key_new);
1003                                                         if (NULL != *language) {
1004                                                                 free(*language);
1005                                                                 *language = NULL;
1006                                                         }
1007                                                         *language = strdup((char*)key_new);
1008                                                 }
1009                                                 xmlFree(key_new);
1010                                                 key_new = NULL;
1011                                         }
1012                                         xmlFree(key_old);
1013                                         key_old = NULL;
1014                                 }
1015                         } else {
1016                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
1017                         }
1018                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_VOICE_TYPE)) {
1019                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_VOICE_TYPE)) {
1020                                 key_old = xmlNodeGetContent(cur_old);
1021                                 if (NULL != key_old) {
1022                                         key_new = xmlNodeGetContent(cur_new);
1023                                         if (NULL != key_new) {
1024                                                 if (0 != xmlStrcmp(key_old, key_new)) {
1025                                                         SLOG(LOG_DEBUG, tts_tag(), "Old voice type(%s), New voice type(%s)", 
1026                                                                 (char*)key_old, (char*)key_new);
1027                                                         if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_FEMALE)) {
1028                                                                 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_FEMALE;
1029                                                         } else if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_MALE)) {
1030                                                                 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_MALE;
1031                                                         } else if (0 == xmlStrcmp(key_new, (const xmlChar *)TTS_TAG_VOICE_TYPE_CHILD)) {
1032                                                                 *voice_type = (int)TTS_CONFIG_VOICE_TYPE_CHILD;
1033                                                         } else {
1034                                                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] New voice type is not valid");
1035                                                         }
1036                                                 }
1037                                                 xmlFree(key_new);
1038                                                 key_new = NULL;
1039                                         }
1040                                         xmlFree(key_old);
1041                                         key_old = NULL;
1042                                 }
1043                         } else {
1044                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
1045                         }
1046                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_SPEECH_RATE)) {
1047                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_SPEECH_RATE)) {
1048                                 key_old = xmlNodeGetContent(cur_old);
1049                                 if (NULL != key_old) {
1050                                         key_new = xmlNodeGetContent(cur_new);
1051                                         if (NULL != key_new) {
1052                                                 if (0 != xmlStrcmp(key_old, key_new)) {
1053                                                         SLOG(LOG_DEBUG, tts_tag(), "Old speech rate(%s), New speech rate(%s)", 
1054                                                                 (char*)key_old, (char*)key_new);
1055                                                         *speech_rate = atoi((char*)key_new);
1056                                                 }
1057                                                 xmlFree(key_new);
1058                                                 key_new = NULL;
1059                                         }
1060                                         xmlFree(key_old);
1061                                         key_old = NULL;
1062                                 }
1063                         } else {
1064                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
1065                         }
1066                 } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)TTS_TAG_CONFIG_PITCH)) {
1067                         if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)TTS_TAG_CONFIG_PITCH)) {
1068                                 key_old = xmlNodeGetContent(cur_old);
1069                                 if (NULL != key_old) {
1070                                         key_new = xmlNodeGetContent(cur_new);
1071                                         if (NULL != key_new) {
1072                                                 if (0 != xmlStrcmp(key_old, key_new)) {
1073                                                         SLOG(LOG_DEBUG, tts_tag(), "Old pitch(%s), New pitch(%s)", 
1074                                                                 (char*)key_old, (char*)key_new);
1075                                                         *pitch = atoi((char*)key_new);
1076                                                 }
1077                                                 xmlFree(key_new);
1078                                                 key_new = NULL;
1079                                         }
1080                                         xmlFree(key_old);
1081                                         key_old = NULL;
1082                                 }
1083                         } else {
1084                                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] old config and new config are different");
1085                         }
1086                 } else {
1087
1088                 }
1089
1090                 cur_new = cur_new->next;
1091                 cur_old = cur_old->next;
1092         }
1093
1094         if (NULL != g_config_doc) {
1095                 xmlFreeDoc(g_config_doc);
1096                 g_config_doc = NULL;
1097         }
1098         g_config_doc = doc;
1099
1100         return 0;
1101 }
1102
1103 int tts_parser_reset()
1104 {
1105         SLOG(LOG_DEBUG, tts_tag(), "[DEBUG] Reset g_config_doc as %s", TTS_DEFAULT_CONFIG);
1106
1107         if (NULL != g_config_doc) {
1108                 xmlFreeDoc(g_config_doc);
1109                 g_config_doc = NULL;
1110         }
1111
1112         g_config_doc = xmlParseFile(TTS_DEFAULT_CONFIG);
1113         if (NULL == g_config_doc) {
1114                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to parse %s", TTS_DEFAULT_CONFIG);
1115                 return -1;
1116         }
1117
1118         int ret = xmlSaveFile(TTS_CONFIG, g_config_doc);
1119         if (0 > ret) {
1120                 SLOG(LOG_ERROR, tts_tag(), "[ERROR] Fail to save %s", TTS_CONFIG);
1121         }
1122
1123         return 0;
1124 }