source: trunk/lib/lang/lang.c @ 1393

Revision 1393, 4.2 KB checked in by philmoz, 19 months ago (diff)

Optimisation of language strings memory usage, and update to Russian language file (from tsvstar).
http://chdk.setepontos.com/index.php?topic=650.msg75171#msg75171.

  • Property svn:eol-style set to native
Line 
1#include "stdlib.h"
2#include "lang.h"
3
4static char* preparsed_lang_default_start=0;
5static char* preparsed_lang_default_end=0;            // @this is for correct detection which is in heap
6
7//-------------------------------------------------------------------
8
9static char** strings = NULL;        // string list (allocated at heap or mapped from gui_lang.c);
10static int count = 0;                // current maximal string id (init at lang_init with GUI_LANG_ITEMS)
11
12//-------------------------------------------------------------------
13void lang_init(int num) {
14    int i;
15    char* str;
16
17    if (strings) {
18       for (i=0; i<count; ++i) {
19           str=strings[i];
20           if ( str && ( str<preparsed_lang_default_start || str>preparsed_lang_default_end ) )
21               free(str);
22    }
23
24       free(strings);
25       count = 0;
26    }
27
28    ++num;
29    strings = malloc(num*sizeof(char*));
30    if (strings) {
31        memset(strings, 0, num*sizeof(char*));
32        count = num;
33    }
34
35}
36
37// add to string list string "str" with id "num"
38//-------------------------------------------------------------------
39static void lang_add_string(int num, const char *str) {
40    int f=0;
41    char *p;
42
43    if (strings && num<count) {
44    p = strings[num];
45       if ( p && ( p<preparsed_lang_default_start || p>preparsed_lang_default_end ) )
46           free( p );
47
48       p = strings[num] = malloc(strlen(str)+1);
49       if (p) {
50           for (; *str; ++str) {
51                if (f) {
52                    if (*str == '"' || *str == '\\') *(p-1)=*str;
53                    else if (*str == 'n') *(p-1)='\n';
54                    else *p++=*str;
55                    f = 0;
56                } else {
57                    *p++=*str;
58                    if (*str == '\\') {
59                        f = 1;
60                    }
61                }
62           }
63           *p=0;
64       }
65    }
66}
67
68// Parsing of loaded .lng file
69// buf - source array (content of file.lng )
70//-------------------------------------------------------------------
71void lang_parse_from_mem(char *buf) {
72    char *p, *s, *e;
73    int i;
74
75    e = buf-1;
76    while(e) {
77        p = e+1;
78        while (*p && (*p=='\r' || *p=='\n')) ++p; //skip empty lines
79        i = strtol(p, &e, 0/*autodetect base oct-dec-hex*/);    // convert "*p" to long "i" and return pointer beyond to e
80        if (e!=p) {
81            p = e;
82            e = strpbrk(p, "\r\n");        //break string with zero on \r|\n
83            if (e) *e=0;
84
85            while (*p && *p!='\"') ++p;    // cut string from "" if it exists
86            if (*p) ++p;
87            s = p;
88            while (*p && (*p!='\"' || *(p-1)=='\\')) ++p;
89            *p=0;
90
91            lang_add_string(i, s);        // add string
92        } else { //skip invalid line
93            e = strpbrk(p, "\r\n");
94            if (e) *e=0;
95        }
96    }
97}
98
99// This function have to be called before any other string load
100//-------------------------------------------------------------------
101void lang_map_preparsed_from_mem( char* gui_lang_default, int num )
102{
103    int i;
104    char *p = gui_lang_default;
105
106    preparsed_lang_default_start = p;
107    lang_init( num );
108    for ( i = 1; i<=num; i++ )
109    {
110        strings[i]=p;
111        while (*p) p++;
112        p++;
113    }
114
115    preparsed_lang_default_end = p;
116}
117
118
119// Universal file processor
120// Load file, process by callback, unalloc/close file
121//-------------------------------------------------------------------
122void load_from_file(const char *filename, callback_process_file callback)
123{
124    int f, size;
125    static struct stat st;
126    char *buf;
127
128    f = open(filename, O_RDONLY, 0777);
129    if (f>=0) {
130        size = (stat((char*)filename, &st)==0)?st.st_size:0;
131        if (size) {
132            buf = umalloc(size+1);
133            if (buf) {
134                size = read(f, buf, size);
135                buf[size]=0;
136                callback(buf);
137                ufree(buf);
138            }
139        }
140        close(f);
141    }
142}
143
144void lang_load_from_file(const char *filename) {
145    load_from_file( filename, lang_parse_from_mem );
146}
147
148
149//-------------------------------------------------------------------
150char* lang_str(int str) {
151    if (str && str<0x1000) {
152        return (strings && str<count && strings[str])?strings[str]:"";
153    } else { // not ID, just char*
154        return (char*)str;
155    }
156}
Note: See TracBrowser for help on using the repository browser.