Back to index

gcompris  8.2.2
wordlist.c
Go to the documentation of this file.
00001 /* gcompris - wordlist.h
00002  *
00003  * Copyright (C) 2003 GCompris Developpement Team
00004  *
00005  *   This program is free software; you can redistribute it and/or modify
00006  *   it under the terms of the GNU General Public License as published by
00007  *   the Free Software Foundation; either version 2 of the License, or
00008  *   (at your option) any later version.
00009  *
00010  *   This program is distributed in the hope that it will be useful,
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *   GNU General Public License for more details.
00014  *
00015  *   You should have received a copy of the GNU General Public License
00016  *   along with this program; if not, write to the Free Software
00017  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  */
00019 
00020 #include <libxml/tree.h>
00021 #include <libxml/parser.h>
00022 #include <string.h>
00023 
00024 #include "gcompris.h"
00025 
00056 GcomprisWordlist
00057 *gc_wordlist_get_from_file(const gchar *format, ...)
00058 {
00059   va_list args;
00060   gchar* xmlfilename;
00061   gchar* filename;
00062   xmlDocPtr xmldoc;
00063   xmlNodePtr wlNode;
00064   xmlNodePtr node;
00065   xmlNodePtr wordsNode;
00066   int i;
00067   guint number_of_level = 0;
00068 
00069   GcomprisWordlist     *wordlist;
00070   xmlChar              *text;
00071 
00072   gchar               **wordsArray;
00073   GSList                *words = NULL;
00074 
00075   if (!format)
00076     return NULL;
00077 
00078   va_start (args, format);
00079   filename = g_strdup_vprintf (format, args);
00080   va_end (args);
00081 
00082   xmlfilename = gc_file_find_absolute(filename);
00083 
00084   /* if the file doesn't exist */
00085   if(!xmlfilename)
00086     {
00087       g_warning("Couldn't find file %s !", filename);
00088       g_free(xmlfilename);
00089       return NULL;
00090     }
00091 
00092   g_warning("Wordlist found %s\n", xmlfilename);
00093 
00094   xmldoc = xmlParseFile(xmlfilename);
00095   g_free(xmlfilename);
00096 
00097   if(!xmldoc){
00098     g_warning("Couldn't parse file %s !", xmlfilename);
00099     return NULL;
00100   }
00101 
00102   if(/* if there is no root element */
00103      !xmldoc->children ||
00104      /* if it doesn't have a name */
00105      !xmldoc->children->name ||
00106      /* if it isn't a GCompris node */
00107      g_strcasecmp((gchar *)xmldoc->children->name,(gchar *)"GCompris")!=0) {
00108     g_warning("No Gcompris node");
00109     xmlFreeDoc(xmldoc);
00110     return NULL;
00111   }
00112 
00113   /* there is only one element child */
00114   wlNode = xmldoc->children->children;
00115   while((wlNode!=NULL)&&(wlNode->type!=XML_ELEMENT_NODE))
00116     wlNode = wlNode->next;
00117 
00118   if((wlNode==NULL)||
00119      g_strcasecmp((gchar *)wlNode->name,"Wordlist")!=0) {
00120     g_warning("No wordlist node %s", (wlNode == NULL) ? (gchar *)wlNode->name : "NULL node");
00121     xmlFreeDoc(xmldoc);
00122     return NULL;
00123   }
00124 
00125 
00126   /* ok, we can process the wordlist */
00127   wordlist = g_malloc0(sizeof(GcomprisWordlist));
00128 
00129   wordlist->filename = g_strdup(filename);
00130 
00131   /* Get name */
00132   text = xmlGetProp ( wlNode,
00133                     (const xmlChar *) "name");
00134 
00135   if (text) {
00136     wordlist->name = g_strdup ((gchar *) text);
00137     xmlFree (text);
00138   }
00139 
00140 
00141   /* Get description */
00142   text = xmlGetProp ( wlNode,
00143                     (const xmlChar *) "description");
00144   if (text) {
00145     wordlist->description = g_strdup ((gchar *) text);
00146     xmlFree (text);
00147   }
00148 
00149   /* Get locale */
00150   text = xmlGetProp ( wlNode,
00151                     (const xmlChar *) "locale");
00152   if (text) {
00153     wordlist->locale = g_strdup ((gchar *) text);
00154     xmlFree (text);
00155   }
00156 
00157   /* Levels loop */
00158 
00159   node = wlNode->children;
00160   while((node!=NULL)) {
00161     words = NULL;
00162     if (node->type!=XML_ELEMENT_NODE){
00163       node = node->next;
00164       continue;
00165     }
00166 
00167     if (strcmp((char *)node->name,"level")!=0){
00168       g_warning("Parsing %s error", filename);
00169       break;
00170     }
00171 
00172     wordsNode = node->children;
00173     if (wordsNode->type!=XML_TEXT_NODE){
00174       g_warning("Parsing %s error", filename);
00175       break;
00176     }
00177 
00178     text = xmlNodeGetContent ( wordsNode);
00179 
00180     wordsArray = g_strsplit_set ((const gchar *) text,
00181                              (const gchar *) " \n\t",
00182                              0);
00183 
00184     g_warning("Wordlist read : %s", text);
00185 
00186     xmlFree (text);
00187 
00188     i=0;
00189     while (wordsArray[i] != NULL) {
00190       if (wordsArray[i][0]!='\0')
00191        words = g_slist_append( words, g_strdup( wordsArray[i]));
00192       i++;
00193     }
00194 
00195     g_strfreev ( wordsArray);
00196 
00197 
00198     /* initialise LevelWordlist struct */
00199     LevelWordlist *level_words = g_malloc0(sizeof(LevelWordlist));
00200 
00201     number_of_level++;
00202 
00203     text = xmlGetProp ( node,
00204                      (const xmlChar *) "value");
00205     if (text) {
00206       level_words->level = atoi((gchar *) text);
00207       xmlFree (text);
00208     }
00209 
00210     level_words->words = words;
00211 
00212     wordlist->levels_words = g_slist_append( wordlist->levels_words, level_words);
00213 
00214     node = node->next;
00215   }
00216 
00217   wordlist->number_of_level = number_of_level;
00218 
00219   return wordlist;
00220 }
00221 
00229 gchar *
00230 gc_wordlist_random_word_get(GcomprisWordlist *wordlist, guint level)
00231 {
00232   GSList *lev_list, *list;
00233 
00234   if(!wordlist)
00235     return NULL;
00236 
00237   lev_list = wordlist->levels_words;
00238 
00239   /* cap to the number_of_level */
00240   if(level > wordlist->number_of_level)
00241     level = wordlist->number_of_level;
00242 
00243   for (list = lev_list; list != NULL; list = list->next)
00244     {
00245       LevelWordlist *lw = list->data;
00246 
00247       if(lw->level == level)
00248        {
00249          gchar *word;
00250          g_warning("Level : %d", lw->level);
00251 
00252          /* We got the proper level, find a random word */
00253          word = (gchar *)g_slist_nth_data(lw->words,
00254                                      RAND(0, g_slist_length(lw->words)-1)
00255                                      );
00256          g_warning("returning random word '%s'", word);
00257          return(g_strdup(word));
00258        }
00259     }
00260 
00261   return NULL;
00262 }
00263 
00269 void
00270 gc_wordlist_free(GcomprisWordlist *wordlist)
00271 {
00272   GSList *list, *words;
00273 
00274   if(!wordlist)
00275     return;
00276 
00277   g_free ( wordlist->filename);
00278   g_free ( wordlist->description);
00279   g_free ( wordlist->locale);
00280   g_free ( wordlist->name);
00281 
00282   for ( list = wordlist->levels_words; list !=NULL; list=list->next){
00283     LevelWordlist *lw = (LevelWordlist *)list->data;
00284     for ( words = lw->words; words !=NULL; words = words->next)
00285       g_free(words->data);
00286     g_slist_free(lw->words);
00287     g_free(lw);
00288   }
00289   g_slist_free ( wordlist->levels_words);
00290   g_free (wordlist);
00291 }