home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 June / CHIP_CD_2004-06.iso / software / miranda_hit / files / mirinstsetup.exe / Miranda Installer 0.0.1.2 / langpack.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-04-20  |  6.9 KB  |  231 lines

  1. /*
  2.  
  3. Miranda IM: the free IM client for Microsoft* Windows*
  4. This is a modified copy of Miranda IM's Language Pack module.
  5. Modified on: November 21st, 2003
  6.  
  7. Copyright 2000-2003 Miranda ICQ/IM project, 
  8. all portions of this codebase are copyrighted to the people 
  9. listed in contributors.txt.
  10.  
  11. This program is free software; you can redistribute it and/or
  12. modify it under the terms of the GNU General Public License
  13. as published by the Free Software Foundation; either version 2
  14. of the License, or (at your option) any later version.
  15.  
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. GNU General Public License for more details.
  20.  
  21. You should have received a copy of the GNU General Public License
  22. along with this program; if not, write to the Free Software
  23. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  24. */
  25. #include "../MirandaInstaller.h"
  26. #pragma hdrstop
  27.  
  28. struct LangPackEntry {
  29.     unsigned linePos;
  30.     DWORD englishHash;
  31.     char *english;      //not currently used, the hash does everything
  32.     char *local;
  33. };
  34.  
  35. struct LangPackStruct {
  36. //    char filename[MAX_PATH];
  37.     char language[64];
  38.     char lastModifiedUsing[64];
  39.     char authors[256];
  40.     char authorEmail[128];
  41.     struct LangPackEntry *entry;
  42.     int entryCount;
  43. } static langPack;
  44.  
  45. static void TrimString(char *str)
  46. {
  47.     int len,start;
  48.     len=lstrlen(str);
  49.     while(str[0] && (unsigned char)str[len-1]<=' ') str[--len]=0;
  50.     for(start=0;str[start] && (unsigned char)str[start]<=' ';start++);
  51.     MoveMemory(str,str+start,len-start+1);
  52. }
  53.  
  54. static void ConvertBackslashes(char *str)
  55. {
  56.     char *pstr;
  57.     for(pstr=str;*pstr;pstr=CharNext(pstr)) {
  58.         if(*pstr=='\\') {
  59.             switch(pstr[1]) {
  60.                 case 'n': *pstr='\n'; break;
  61.                 case 't': *pstr='\t'; break;
  62.                 default: *pstr=pstr[1]; break;
  63.             }
  64.             MoveMemory(pstr+1,pstr+2,lstrlen(pstr+2)+1);
  65.         }
  66.     }
  67. }
  68.  
  69. static DWORD LangPackHash(const char *szStr)
  70. {
  71. #if defined _M_IX86 && !defined _NUMEGA_BC_FINALCHECK
  72.     __asm {                //this is mediocrely optimised, but I'm sure it's good enough
  73.         xor  edx,edx
  74.         mov  esi,szStr
  75.         xor  cl,cl
  76.     lph_top:
  77.         xor  eax,eax
  78.         and  cl,31
  79.         mov  al,[esi]
  80.         inc  esi
  81.         test al,al
  82.         jz   lph_end
  83.         rol  eax,cl
  84.         add  cl,5
  85.         xor  edx,eax
  86.         jmp  lph_top
  87.     lph_end:
  88.         mov  eax,edx
  89.     }
  90. #else
  91.     DWORD hash=0;
  92.     int i;
  93.     int shift=0;
  94.     for(i=0;szStr[i];i++) {
  95.         hash^=szStr[i]<<shift;
  96.         if(shift>24) hash^=(szStr[i]>>(32-shift))&0x7F;
  97.         shift=(shift+5)&0x1F;
  98.     }
  99.     return hash;
  100. #endif
  101. }
  102.  
  103. static int SortLangPackHashesProc(struct LangPackEntry *arg1,struct LangPackEntry *arg2)
  104. {
  105.     if(arg1->englishHash<arg2->englishHash) return -1;
  106.     if(arg1->englishHash>arg2->englishHash) return 1;
  107.     /* both source strings of the same hash (may not be the same string thou) put
  108.     the one that was written first to be found first */
  109.     if(arg1->linePos<arg2->linePos) return -1;
  110.     if(arg1->linePos>arg2->linePos) return 1;
  111.     return 0;
  112. }
  113.  
  114.  
  115. static int SortLangPackHashesProc2(struct LangPackEntry *arg1,struct LangPackEntry *arg2)
  116. {
  117.     if(arg1->englishHash<arg2->englishHash) return -1;
  118.     if(arg1->englishHash>arg2->englishHash) return 1;
  119.     return 0;
  120. }
  121.  
  122.  
  123.  
  124. char *Translate(const char *szEnglish)
  125. {
  126.     struct LangPackEntry key,*entry;
  127.  
  128.     key.englishHash=LangPackHash(szEnglish);
  129.     entry=(struct LangPackEntry*)bsearch(&key,langPack.entry,langPack.entryCount,sizeof(struct LangPackEntry),(int(*)(const void*,const void*))SortLangPackHashesProc2);
  130.     if(entry==NULL) return (char*)szEnglish;
  131.     while(entry>langPack.entry)
  132.     {
  133.         entry--;
  134.         if(entry->englishHash!=key.englishHash) {
  135.             entry++;
  136.             return entry->local;
  137.         }
  138.     }
  139.     return entry->local;
  140. }
  141.  
  142.  
  143.  
  144. void LP_Init(void)
  145. {
  146.     FILE *fp;
  147.     char line[4096];
  148.     char *pszColon;
  149.     int entriesAlloced;
  150.     int startOfLine=0;
  151.     unsigned int linePos=1;
  152.     char szCDir[MAX_PATH + 1];
  153.  
  154.     GetModuleFileName(NULL,szCDir,MAX_PATH + 1);
  155.     *(strrchr(szCDir,'\\')+1) = '\0';
  156.     lstrcat(szCDir,"langpack.txt");
  157.  
  158.     fp=fopen(szCDir,"rt");
  159.     if(fp==NULL) return;
  160.     fgets(line,sizeof(line),fp);
  161.     TrimString(line);
  162.     if(lstrcmp(line,"Miranda Language Pack Version 1")) {fclose(fp); return;}
  163.     //headers
  164.     while(!feof(fp)) {
  165.         startOfLine=ftell(fp);
  166.         if(fgets(line,sizeof(line),fp)==NULL) break;
  167.         TrimString(line);
  168.         if(line[0]==';' || line[0]==0) continue;
  169.         if(line[0]=='[') break;
  170.         pszColon=strchr(line,':');
  171.         if(pszColon==NULL) {fclose(fp); return;}
  172.         *pszColon=0;
  173.         if(!lstrcmp(line,"Language")) {lstrcpy(langPack.language,pszColon+1); TrimString(langPack.language);}
  174.         else if(!lstrcmp(line,"Last-Modified-Using")) {lstrcpy(langPack.lastModifiedUsing,pszColon+1); TrimString(langPack.lastModifiedUsing);}
  175.         else if(!lstrcmp(line,"Authors")) {lstrcpy(langPack.authors,pszColon+1); TrimString(langPack.authors);}
  176.         else if(!lstrcmp(line,"Author-email")) {lstrcpy(langPack.authorEmail,pszColon+1); TrimString(langPack.authorEmail);}
  177.     }
  178.     //body
  179.     fseek(fp,startOfLine,SEEK_SET);
  180.     entriesAlloced=0;
  181.     while(!feof(fp)) {
  182.         if(fgets(line,sizeof(line),fp)==NULL) break;
  183.         TrimString(line);
  184.         if(line[0]==';' || line[0]==0) continue;
  185.         ConvertBackslashes(line);
  186.         if(line[0]=='[' && line[lstrlen(line)-1]==']') {
  187.             if(langPack.entryCount && langPack.entry[langPack.entryCount-1].local==NULL) {
  188.                 if(langPack.entry[langPack.entryCount-1].english!=NULL) free(langPack.entry[langPack.entryCount-1].english);
  189.                 langPack.entryCount--;
  190.             }
  191.             line[0]=' '; line[lstrlen(line)-1]=' ';
  192.             TrimString(line);
  193.             if(++langPack.entryCount>entriesAlloced) {
  194.                 entriesAlloced+=128;
  195.                 langPack.entry=(struct LangPackEntry*)realloc(langPack.entry,sizeof(struct LangPackEntry)*entriesAlloced);
  196.             }
  197.             //langPack.entry[langPack.entryCount-1].english=_strdup(line);
  198.             langPack.entry[langPack.entryCount-1].english=NULL;
  199.             langPack.entry[langPack.entryCount-1].englishHash=LangPackHash(line);
  200.             langPack.entry[langPack.entryCount-1].local=NULL;
  201.             langPack.entry[langPack.entryCount-1].linePos=linePos++;
  202.         }
  203.         else if(langPack.entryCount) {
  204.             if(langPack.entry[langPack.entryCount-1].local==NULL)
  205.                 langPack.entry[langPack.entryCount-1].local=_strdup(line);
  206.             else {
  207.                 langPack.entry[langPack.entryCount-1].local=(char*)realloc(langPack.entry[langPack.entryCount-1].local,lstrlen(langPack.entry[langPack.entryCount-1].local)+lstrlen(line)+2);
  208.                 lstrcat(langPack.entry[langPack.entryCount-1].local,"\n");
  209.                 lstrcat(langPack.entry[langPack.entryCount-1].local,line);
  210.             }
  211.         }
  212.     }
  213.     qsort(langPack.entry,langPack.entryCount,sizeof(struct LangPackEntry),(int(*)(const void*,const void*))SortLangPackHashesProc);
  214.     fclose(fp);
  215. }
  216.  
  217.  
  218.  
  219. void LP_UnInit(void)
  220. {
  221.     int i;
  222.     for(i=0;i<langPack.entryCount;i++) {
  223.         if(langPack.entry[i].english!=NULL) free(langPack.entry[i].english);
  224.         if(langPack.entry[i].local!=NULL) { free(langPack.entry[i].local); }
  225.     }
  226.     if(langPack.entryCount) {
  227.         free(langPack.entry);
  228.         langPack.entry=0;
  229.         langPack.entryCount=0;
  230.     }
  231. }