fb607a46f8ac06feea462eccfe5b6ddbc408851f
2 * lmo - Lua Machine Objects - PO to LMO conversion tool
4 * Copyright (C) 2009-2012 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.
19 #include "template_lmo.h"
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 static int cmp_index(const void *a
, const void *b
)
87 uint32_t x
= ntohl(((const lmo_entry_t
*)a
)->key_id
);
88 uint32_t y
= ntohl(((const lmo_entry_t
*)b
)->key_id
);
98 static void print_index(void *array
, int n
, FILE *out
)
102 qsort(array
, n
, sizeof(*e
), cmp_index
);
104 for (e
= array
; n
> 0; n
--, e
++)
106 print(&e
->key_id
, sizeof(uint32_t), 1, out
);
107 print(&e
->val_id
, sizeof(uint32_t), 1, out
);
108 print(&e
->offset
, sizeof(uint32_t), 1, out
);
109 print(&e
->length
, sizeof(uint32_t), 1, out
);
113 int main(int argc
, char *argv
[])
124 lmo_entry_t
*entry
= NULL
;
125 uint32_t key_id
, val_id
;
130 if( (argc
!= 3) || ((in
= fopen(argv
[1], "r")) == NULL
) || ((out
= fopen(argv
[2], "w")) == NULL
) )
133 memset(line
, 0, sizeof(key
));
134 memset(key
, 0, sizeof(val
));
135 memset(val
, 0, sizeof(val
));
137 while( (NULL
!= fgets(line
, sizeof(line
), in
)) || (state
>= 2 && feof(in
)) )
139 if( state
== 0 && strstr(line
, "msgid \"") == line
)
141 switch(extract_string(line
, key
, sizeof(key
)))
144 die("Syntax error in msgid");
152 else if( state
== 1 || state
== 2 )
154 if( strstr(line
, "msgstr \"") == line
|| state
== 2 )
156 switch(extract_string(line
, val
, sizeof(val
)))
167 switch(extract_string(line
, tmp
, sizeof(tmp
)))
177 else if( state
== 3 )
179 switch(extract_string(line
, tmp
, sizeof(tmp
)))
191 if( strlen(key
) > 0 && strlen(val
) > 0 )
193 key_id
= sfh_hash(key
, strlen(key
));
194 val_id
= sfh_hash(val
, strlen(val
));
196 if( key_id
!= val_id
)
199 array
= realloc(array
, n_entries
* sizeof(lmo_entry_t
));
200 entry
= (lmo_entry_t
*)array
+ n_entries
- 1;
203 die("Out of memory");
205 entry
->key_id
= htonl(key_id
);
206 entry
->val_id
= htonl(val_id
);
207 entry
->offset
= htonl(offset
);
208 entry
->length
= htonl(strlen(val
));
210 length
= strlen(val
) + ((4 - (strlen(val
) % 4)) % 4);
212 print(val
, length
, 1, out
);
218 memset(key
, 0, sizeof(key
));
219 memset(val
, 0, sizeof(val
));
222 memset(line
, 0, sizeof(line
));
225 print_index(array
, n_entries
, out
);
229 offset
= htonl(offset
);
230 print(&offset
, sizeof(uint32_t), 1, out
);