2 * lmo - Lua Machine Objects - PO to LMO conversion tool
4 * Copyright (C) 2009-2011 Jo-Philipp Wich <xm@subsignal.org>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
21 static void die(const char *msg)
23 fprintf(stderr, "Error: %s\n", msg);
27 static void usage(const char *name)
29 fprintf(stderr, "Usage: %s input.po output.lmo\n", name);
33 static void print(const void *ptr, size_t size, size_t nmemb, FILE *stream)
35 if( fwrite(ptr, size, nmemb, stream) == 0 )
36 die("Failed to write stdout");
39 static int extract_string(const char *src, char *dest, int len)
45 for( pos = 0; (pos < strlen(src)) && (pos < len); pos++ )
47 if( (off == -1) && (src[pos] == '"') )
62 dest[pos-off] = src[pos];
65 else if( src[pos] == '\\' )
67 dest[pos-off] = src[pos];
70 else if( src[pos] != '"' )
72 dest[pos-off] = src[pos];
82 return (off > -1) ? strlen(dest) : -1;
85 int main(int argc, char *argv[])
94 uint32_t key_id, val_id;
99 lmo_entry_t *head = NULL;
100 lmo_entry_t *entry = NULL;
102 if( (argc != 3) || ((in = fopen(argv[1], "r")) == NULL) || ((out = fopen(argv[2], "w")) == NULL) )
105 memset(line, 0, sizeof(key));
106 memset(key, 0, sizeof(val));
107 memset(val, 0, sizeof(val));
109 while( (NULL != fgets(line, sizeof(line), in)) || (state >= 2 && feof(in)) )
111 if( state == 0 && strstr(line, "msgid \"") == line )
113 switch(extract_string(line, key, sizeof(key)))
116 die("Syntax error in msgid");
124 else if( state == 1 || state == 2 )
126 if( strstr(line, "msgstr \"") == line || state == 2 )
128 switch(extract_string(line, val, sizeof(val)))
139 switch(extract_string(line, tmp, sizeof(tmp)))
149 else if( state == 3 )
151 switch(extract_string(line, tmp, sizeof(tmp)))
163 if( strlen(key) > 0 && strlen(val) > 0 )
165 key_id = sfh_hash(key, strlen(key));
166 val_id = sfh_hash(val, strlen(val));
168 if( key_id != val_id )
170 if( (entry = (lmo_entry_t *) malloc(sizeof(lmo_entry_t))) != NULL )
172 memset(entry, 0, sizeof(entry));
173 length = strlen(val) + ((4 - (strlen(val) % 4)) % 4);
175 entry->key_id = htonl(key_id);
176 entry->val_id = htonl(val_id);
177 entry->offset = htonl(offset);
178 entry->length = htonl(strlen(val));
180 print(val, length, 1, out);
188 die("Out of memory");
194 memset(key, 0, sizeof(key));
195 memset(val, 0, sizeof(val));
198 memset(line, 0, sizeof(line));
202 while( entry != NULL )
204 print(&entry->key_id, sizeof(uint32_t), 1, out);
205 print(&entry->val_id, sizeof(uint32_t), 1, out);
206 print(&entry->offset, sizeof(uint32_t), 1, out);
207 print(&entry->length, sizeof(uint32_t), 1, out);
213 offset = htonl(offset);
214 print(&offset, sizeof(uint32_t), 1, out);