Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

Locale.c

Go to the documentation of this file.
00001 /*
00002  *    gui - [gega user interface] the flexible solution for user interface problems
00003  *    Copyright (C) 2002  Gergely Gati
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; version 2 of the License.
00008  *
00009  *    This program is distributed in the hope that it will be useful,
00010  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *    GNU General Public License for more details.
00013  *
00014  *    You should have received a copy of the GNU General Public License
00015  *    along with this program; if not, write to the Free Software
00016  *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  *
00018  *    Gergely Gati
00019  *      email:           g.gati@freemail.hu
00020  *      AIM screenname:  GatiGergely
00021  *      ICQ number:      93131690
00022  *
00023  */
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <xmlparse.h>
00027 
00028 #include "debug.h"
00029 #include "macros.h"
00030 #include "Locale.h"
00031 #include "Common.h"
00032 #include "Memory.h"
00033 #include "Net.h"
00034 
00035 
00036 typedef struct LocaleItem_s
00037 {
00038   char *key;
00039   char *value;
00040 } LocaleItem_t;
00041 
00042 struct Locale_s
00043 {
00044   gui_App_t *app;
00045   char *filename;
00046   char lang[3];
00047   int itemcount;
00048   LocaleItem_t *items;      // key-sorted item-vector
00049 };
00050 
00051 typedef struct LocaleParse_s
00052 {
00053   Locale_t *locale;
00054   List_t *keypairlist;
00055   int err;
00056   int parse_status;
00057 } LocaleParse_t;
00058 
00059 
00060 #define ERR_LOC_OK                0
00061 #define ERR_LOC_XML               1
00062 #define ERR_LOC_OUT_OF_MEMORY     2
00063 #define ERR_LOC_ARGUMENT_MISSING  3
00064 #define ERR_LOC_APP_NOTFOUND      4
00065 #define ERR_LOC_CLOSING_NOTFOUND  5
00066 #define ERR_LOC_LOCALE_CANTLOAD   6
00067 
00068 
00069 static u32 (*call_vector[LOCALE_FUNC_DONE-LOCALE_FUNCBASE+1])(tag *);
00070 
00071 static char extension_gui[]="_gui_";
00072 static char extension_xml[]=".xml";
00073 #if DEBUG_LEVEL >= 1
00074 static char *errstr[]=
00075 {
00076   "OK",
00077   "XML Error",
00078   "Out of memory",
00079   "Argument missing",
00080   "App section not found",
00081   "Closing tag not found",
00082   "Locale XML cannot be loaded",
00083   NULL
00084 };
00085 #endif
00086 
00087 static Locale_t *locale_CleanUpInternal(Locale_t *locale)
00088 {
00089   locale_CleanUp(locale);
00090   return(NULL);
00091 }
00092 
00093 
00094 static int locale_cmp(const void *e1, const void *e2)
00095 {
00096   LocaleItem_t *i1=(LocaleItem_t *)e1,*i2=(LocaleItem_t *)e2;
00097   return(strcmp(i1->key,i2->key));
00098 }
00099 
00100 
00101 static void locale_StartElement(void *userData, const char *name, const char **atts)
00102 {
00103   LocaleParse_t *locparse=(LocaleParse_t *)userData;
00104   int i;
00105   char *att,*value,*key;
00106   Node_t *node;
00107   LocaleItem_t *item;
00108 
00109   debug_Begin();
00110 
00111 //printf("locale START> %s\n",name);
00112   if(locparse->parse_status==0)
00113   {
00114     if(strcmp(name,"Translation")==0)
00115     {
00116       if(NULL!=(att=common_GetAttr(atts,"app"))&&strcmp(att,locparse->locale->app->name)==0)
00117       {
00118         locparse->parse_status=1;
00119       }
00120     }
00121   }
00122   else if(locparse->parse_status>0)
00123   {
00124     if(strcmp(name,"String")==0)
00125     {
00126       key=value=NULL;
00127       for(i=0;atts[i]!=NULL;i+=2)
00128       {
00129         if(strcmp(atts[i],"name")==0) key=(char *)atts[i+1];
00130         if(strcmp(atts[i],"value")==0) value=(char *)atts[i+1];
00131       }
00132       if(key!=NULL&&value!=NULL)
00133       {
00134         node=list_CreateNode();
00135         item=mem_malloc(sizeof(LocaleItem_t));
00136         item->key=mem_malloc(strlen(key)+1);
00137         item->value=mem_malloc(strlen(value)+1);
00138         if(node!=NULL&&item!=NULL&&item->key!=NULL&&item->value!=NULL)
00139         {
00140           list_SetNodeData(node,item);
00141           strcpy(item->key,key);
00142           strcpy(item->value,value);
00143           list_InsertNodeHead(locparse->keypairlist,node);
00144         }
00145         else locparse->err=ERR_LOC_OUT_OF_MEMORY;
00146       }
00147       else locparse->err=ERR_LOC_ARGUMENT_MISSING;
00148     }
00149   }
00150 
00151   debug_End();
00152 }
00153 
00154 
00155 static void locale_EndElement(void *userData, const char *name)
00156 {
00157   LocaleParse_t *locparse=(LocaleParse_t *)userData;
00158 
00159   debug_Begin();
00160 
00161   if(locparse->parse_status>0&&strcmp(name,"Translation")==0) locparse->parse_status=-1;
00162 //printf("locale END< %s\n",name);
00163 
00164   debug_End();
00165 }
00166 
00167 
00168 static Locale_t *locale_InitInternal(gui_App_t *app, char *lang)
00169 {
00170   Locale_t *locale=NULL;
00171   LocaleParse_t locparse;
00172   LocaleItem_t *item;
00173   int name_size,xmlret,i;
00174   char *file;
00175   XML_Parser ctxt;
00176   Node_t *node,*nextnode;
00177 
00178   debug_Begin();
00179 
00180   locparse.keypairlist=NULL;
00181   locparse.locale=NULL;
00182   locparse.err=ERR_LOC_OK;
00183   locparse.parse_status=0;
00184   if(lang!=NULL&&NULL!=(locale=mem_calloc(1,sizeof(Locale_t))))
00185   {
00186     // app + "_gui_" + lang + ".xml"
00187     name_size=strlen(app->name)+strlen(extension_gui)+2+strlen(extension_xml);
00188     locale->app=app;
00189     locale->lang[0]=lang[0];
00190     locale->lang[1]=lang[1];
00191     locale->lang[2]='\0';
00192     locale->itemcount=0;
00193     if(NULL!=(locale->filename=mem_malloc(name_size+1)))
00194     {
00195       strcpy(locale->filename,app->name);
00196       strcat(locale->filename,extension_gui);
00197       strcat(locale->filename,locale->lang);
00198       strcat(locale->filename,extension_xml);
00199 //printf("try: '%s'\n",locale->filename);
00200       if(NULL!=(file=(char *)net_LoadFile(TAG_NET_CONN,locale->app->conn,TAG_NET_NAME,locale->filename,TAG_DONE)))
00201       {
00202         locparse.locale=locale;
00203         if(NULL!=(locparse.keypairlist=list_CreateList()))
00204         {
00205           if((ctxt=XML_ParserCreate(NULL)))
00206           {
00207             XML_SetUserData(ctxt,&locparse);
00208             XML_SetElementHandler(ctxt,locale_StartElement,locale_EndElement);
00209             xmlret=XML_Parse(ctxt,file,strlen(file),TRUE);
00210             if(!xmlret)
00211             {
00212               locparse.err=ERR_LOC_XML;
00213               debug_Error("%s: %s at line %d\n",locale->filename,XML_ErrorString(XML_GetErrorCode(ctxt)),XML_GetCurrentLineNumber(ctxt));
00214             }
00215             XML_ParserFree(ctxt);
00216           }
00217           locale->itemcount=list_GetNodeCount(locparse.keypairlist);
00218           if(NULL!=(locale->items=mem_malloc(locale->itemcount*sizeof(LocaleItem_t))))
00219           {
00220             for(i=0,node=list_GetNodeHead(locparse.keypairlist);node!=NULL;node=nextnode,i++)
00221             {
00222               nextnode=list_GetNodeNext(locparse.keypairlist,node);
00223               list_RemoveNode(locparse.keypairlist,node);
00224               if(NULL!=(item=list_GetNodeData(node)))
00225               {
00226                 locale->items[i].key=item->key;
00227                 locale->items[i].value=item->value;
00228                 mem_free(item);
00229               }
00230               list_DeleteNode(node);
00231             }
00232             qsort(locale->items,locale->itemcount,sizeof(LocaleItem_t),locale_cmp);
00233             if(locparse.parse_status>=0||locparse.err!=ERR_LOC_OK)
00234             {
00235               locale=locale_CleanUpInternal(locale);
00236               if(locparse.parse_status==0) locparse.err=ERR_LOC_APP_NOTFOUND;
00237               else if(locparse.parse_status>0) locparse.err=ERR_LOC_CLOSING_NOTFOUND;
00238             }
00239           }
00240           else locale=locale_CleanUpInternal(locale);
00241           list_DeleteList(locparse.keypairlist);
00242         }
00243         mem_free(file);
00244       }
00245       else locale=locale_CleanUpInternal(locale);
00246     }
00247     else locale=locale_CleanUpInternal(locale);
00248   }
00249   if(locale==NULL&&locparse.err!=0) debug_Warning("%s",errstr[locparse.err]);
00250 
00251   debug_End();
00252 
00253   return(locale);
00254 }
00255 
00256 
00257 Locale_t *locale_Init(gui_App_t *app, char **lang, char *default_lang)
00258 {
00259   Locale_t *locale=NULL;
00260   int i;
00261 
00262   debug_Begin();
00263 
00264   call_vector[LOCALE_GETSTRING-LOCALE_FUNCBASE]=locale_GetStringTL;
00265   bases_modules.locale_Call=locale_Call;
00266   bases_modules.locale_CallTL=locale_CallTL;
00267 
00268   if(lang!=NULL) for(i=0;lang[i]!=NULL&&locale==NULL;i++) locale=locale_InitInternal(app,lang[i]);
00269   if(locale==NULL) locale=locale_InitInternal(app,default_lang);
00270   if(locale==NULL) debug_Error("%s",errstr[ERR_LOC_LOCALE_CANTLOAD]);
00271 
00272   debug_End();
00273 
00274   return(locale);
00275 }
00276 
00277 
00278 void locale_CleanUp(Locale_t *locale)
00279 {
00280   int i;
00281 
00282   debug_Begin();
00283 
00284   if(locale!=NULL)
00285   {
00286     if(locale->filename!=NULL) mem_free(locale->filename);
00287     if(locale->items!=NULL)
00288     {
00289       for(i=0;i<locale->itemcount;i++)
00290       {
00291         if(NULL!=locale->items[i].key) mem_free(locale->items[i].key);
00292         if(NULL!=locale->items[i].value) mem_free(locale->items[i].value);
00293       }
00294       mem_free(locale->items);
00295     }
00296     mem_free(locale);
00297   }
00298 
00299   debug_End();
00300 }
00301 
00302 
00307 u32 locale_GetString(u32 firsttag, ...)
00308 {
00309   return(locale_GetStringTL((tag *)&firsttag));
00310 }
00311 u32 locale_GetStringTL(tag *taglist)
00312 {
00313     Locale_t *locale;
00314     char *msg;
00315 
00316   LocaleItem_t key,*found;
00317 
00318   debug_Begin();
00319 
00320   locale=(Locale_t *)tag_GetTagData(taglist,TAG_LOCALE_LOCALE,0L);
00321   msg=(char *)tag_GetTagData(taglist,TAG_LOCALE_MSG,0L);
00322 
00323   if(locale!=NULL)
00324   {
00325     key.key=msg;
00326     found=bsearch(&key,locale->items,locale->itemcount,sizeof(LocaleItem_t),locale_cmp);
00327     if(found!=NULL) msg=found->value;
00328   }
00329 
00330   debug_End();
00331 
00332   return((u32)msg);
00333 }
00334 
00335 
00336 u32 locale_Call(int function, u32 firsttag, ...)
00337 {
00338   return(locale_CallTL(function,(tag *)&firsttag));
00339 }
00340 u32 locale_CallTL(int function, tag *taglist)
00341 {
00342   u32 ret=~0L;
00343 
00344   debug_Begin();
00345 
00346   debug_Message("function ID : %d",function-LOCALE_FUNCBASE);
00347 
00348   if(function>=LOCALE_FUNCBASE&&function<LOCALE_FUNC_DONE)
00349   {
00350     ret=call_vector[function-LOCALE_FUNCBASE](taglist);
00351   }
00352   else debug_Warning("%s(): Function code out of range! code=0x%04x",__FUNCTION__,function);
00353 
00354   debug_End();
00355 
00356   return(ret);
00357 }

Generated on Tue Jan 7 12:11:22 2003 for THEGUI by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002