@@ -59,61 +59,66 @@ const struct mo_hdr def_hdr = {
5959
6060// pass 0: collect numbers of strings, calculate size and offsets for tables
6161// print header
62- // pass 1: create in-memory string tables
62+ // pass 1: print string table [lengths/offsets]
63+ // pass 2: print translation table [lengths/offsets]
64+ // pass 3: print strings
65+ // pass 4: print translations
6366enum passes {
6467 pass_first = 0 ,
6568 pass_collect_sizes = pass_first ,
6669 pass_second ,
70+ pass_print_string_offsets = pass_second ,
71+ pass_print_translation_offsets ,
72+ pass_print_strings ,
73+ pass_print_translations ,
6774 pass_max ,
6875};
6976
70- struct strtbl {
71- unsigned len , off ;
72- };
73-
74- struct strmap {
75- struct strtbl str , * trans ;
76- };
77-
7877struct callbackdata {
7978 enum passes pass ;
8079 unsigned off ;
8180 FILE * out ;
8281 unsigned num [pe_maxstr ];
8382 unsigned len [pe_maxstr ];
84- struct strmap * strlist ;
85- struct strtbl * translist ;
86- char * strbuffer [pe_maxstr ];
87- unsigned stroff [pe_maxstr ];
88- unsigned curr [pe_maxstr ];
8983};
9084
91- static struct callbackdata * cb_for_qsort ;
92- int strmap_comp (const void * a_ , const void * b_ ) {
93- const struct strmap * a = a_ , * b = b_ ;
94- return strcmp (cb_for_qsort -> strbuffer [0 ] + a -> str .off , cb_for_qsort -> strbuffer [0 ] + b -> str .off );
95- }
96-
9785
9886int process_line_callback (struct po_info * info , void * user ) {
9987 struct callbackdata * d = (struct callbackdata * ) user ;
10088 assert (info -> type == pe_msgid || info -> type == pe_msgstr );
10189 switch (d -> pass ) {
10290 case pass_collect_sizes :
10391 d -> num [info -> type ] += 1 ;
104- d -> len [info -> type ] += info -> textlen + 1 ;
92+ d -> len [info -> type ] += info -> textlen ;
10593 break ;
106- case pass_second :
107- memcpy (d -> strbuffer [info -> type ] + d -> stroff [info -> type ], info -> text , info -> textlen + 1 );
108- if (info -> type == pe_msgid )
109- d -> strlist [d -> curr [info -> type ]].str = (struct strtbl ){.len = info -> textlen , .off = d -> stroff [info -> type ]};
110- else {
111- assert (d -> curr [pe_msgid ] == d -> curr [pe_msgstr ]+ 1 );
112- d -> translist [d -> curr [info -> type ]] = (struct strtbl ){.len = info -> textlen , .off = d -> stroff [info -> type ]};
113- d -> strlist [d -> curr [info -> type ]].trans = & d -> translist [d -> curr [info -> type ]];
114- }
115- d -> curr [info -> type ]++ ;
116- d -> stroff [info -> type ]+= info -> textlen + 1 ;
94+ case pass_print_string_offsets :
95+ if (info -> type == pe_msgstr ) break ;
96+ write_offsets :
97+ // print length of current string
98+ fwrite (& info -> textlen , sizeof (unsigned ), 1 , d -> out );
99+ // print offset of current string
100+ fwrite (& d -> off , sizeof (unsigned ), 1 , d -> out );
101+ d -> off += info -> textlen + 1 ;
102+ break ;
103+ case pass_print_translation_offsets :
104+ #ifndef DO_NOTHING
105+ if (info -> type == pe_msgid ) break ;
106+ #else
107+ if (info -> type != pe_msgid ) break ;
108+ #endif
109+ goto write_offsets ;
110+ case pass_print_strings :
111+ if (info -> type == pe_msgstr ) break ;
112+ write_string :
113+ fwrite (info -> text , info -> textlen + 1 , 1 , d -> out );
114+ break ;
115+ case pass_print_translations :
116+ #ifndef DO_NOTHING
117+ if (info -> type == pe_msgid ) break ;
118+ #else
119+ if (info -> type != pe_msgid ) break ;
120+ #endif
121+ goto write_string ;
117122 break ;
118123 default :
119124 abort ();
@@ -144,17 +149,19 @@ int process(FILE *in, FILE *out) {
144149 int invalid_file = 0 ;
145150
146151 mohdr .off_tbl_trans = mohdr .off_tbl_org ;
147- for (d .pass = pass_first ; d .pass <= pass_second ; d .pass ++ ) {
152+ for (d .pass = pass_first ; d .pass < pass_max ; d .pass ++ ) {
148153 if (d .pass == pass_second ) {
149154 // start of second pass:
150155 // check that data gathered in first pass is consistent
156+ #ifndef DO_NOTHING
151157 if (d .num [pe_msgid ] != d .num [pe_msgstr ]) {
152158 // one should actually abort here,
153159 // but gnu gettext simply writes an empty .mo and returns success.
154160 //abort();
155161 d .num [pe_msgid ] = 0 ;
156162 invalid_file = 1 ;
157163 }
164+ #endif
158165
159166 // calculate header fields from len and num arrays
160167 mohdr .numstring = d .num [pe_msgid ];
@@ -165,13 +172,6 @@ int process(FILE *in, FILE *out) {
165172 // set offset startvalue
166173 d .off = mohdr .off_tbl_trans + d .num [pe_msgid ] * (sizeof (unsigned )* 2 );
167174 if (invalid_file ) return 0 ;
168-
169- d .strlist = malloc (d .num [pe_msgid ] * sizeof (struct strmap ));
170- d .translist = malloc (d .num [pe_msgstr ] * sizeof (struct strtbl ));
171- d .strbuffer [pe_msgid ] = malloc (d .len [pe_msgid ]);
172- d .strbuffer [pe_msgstr ] = malloc (d .len [pe_msgstr ]);
173- d .stroff [pe_msgid ] = d .stroff [pe_msgstr ] = 0 ;
174- assert (d .strlist && d .translist && d .strbuffer [0 ] && d .strbuffer [1 ]);
175175 }
176176 poparser_init (p , convbuf , sizeof (convbuf ), process_line_callback , & d );
177177
@@ -183,21 +183,6 @@ int process(FILE *in, FILE *out) {
183183
184184 fseek (in , 0 , SEEK_SET );
185185 }
186-
187- cb_for_qsort = & d ;
188- qsort (d .strlist , d .num [pe_msgid ], sizeof (struct strmap ), strmap_comp );
189- unsigned i ;
190- for (i = 0 ; i < d .num [0 ]; i ++ ) {
191- d .strlist [i ].str .off += d .off ;
192- fwrite (& d .strlist [i ].str , sizeof (struct strtbl ), 1 , d .out );
193- }
194- for (i = 0 ; i < d .num [1 ]; i ++ ) {
195- d .strlist [i ].trans -> off += d .off + d .len [0 ];
196- fwrite (d .strlist [i ].trans , sizeof (struct strtbl ), 1 , d .out );
197- }
198- fwrite (d .strbuffer [0 ], d .len [0 ], 1 , d .out );
199- fwrite (d .strbuffer [1 ], d .len [1 ], 1 , d .out );
200-
201186 return 0 ;
202187}
203188
0 commit comments