diff options
author | Jo-Philipp Wich <jow@openwrt.org> | 2012-11-25 19:17:55 +0000 |
---|---|---|
committer | Jo-Philipp Wich <jow@openwrt.org> | 2012-11-25 19:17:55 +0000 |
commit | 0e50aa690af6cd9f37fa97b4a521fe523cce3c39 (patch) | |
tree | c0ab4edc0dd221dfa3e6fb4eeba049ecc05326fe /libs/lmo/src | |
parent | c647ff9f0e1af211a762dc9a773c1b5c4aacd168 (diff) |
libs/web: rewrite template engine, merge lmo library
- template parser: merge lmo library
- template parser: rewrite to operate on memory mapped files
- template parser: implement proper line number reporting on syntax errors
- template parser: process translate tags directly and bypass Lua
- template lmo: introduce load_catalog(), change_catalog() and close_catalog()
- template lmo: rewrite index processing to operate directly on the memory mapped file
- template lmo: implement binary search keys, reducing the lookup complexity to O(log n)
- po2lmo: write sorted indixes when generating *.lmo archives
- i18n: use the template parser for translations
- i18n: stub load(), loadc() and clear()
- i18n: map setlanguage() to load_catalog()
Diffstat (limited to 'libs/lmo/src')
-rw-r--r-- | libs/lmo/src/lmo.h | 72 | ||||
-rw-r--r-- | libs/lmo/src/lmo_core.c | 234 | ||||
-rw-r--r-- | libs/lmo/src/lmo_hash.c | 53 | ||||
-rw-r--r-- | libs/lmo/src/lmo_lookup.c | 58 | ||||
-rw-r--r-- | libs/lmo/src/lmo_lualib.c | 263 | ||||
-rw-r--r-- | libs/lmo/src/lmo_lualib.h | 43 | ||||
-rw-r--r-- | libs/lmo/src/lmo_po2lmo.c | 226 |
7 files changed, 0 insertions, 949 deletions
diff --git a/libs/lmo/src/lmo.h b/libs/lmo/src/lmo.h deleted file mode 100644 index ab17e873f..000000000 --- a/libs/lmo/src/lmo.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * lmo - Lua Machine Objects - General header - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _LMO_H_ -#define _LMO_H_ - -#include <stdlib.h> -#include <stdio.h> -#include <stdint.h> -#include <string.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <arpa/inet.h> -#include <unistd.h> -#include <errno.h> - - -#if (defined(__GNUC__) && defined(__i386__)) -#define sfh_get16(d) (*((const uint16_t *) (d))) -#else -#define sfh_get16(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\ - +(uint32_t)(((const uint8_t *)(d))[0]) ) -#endif - - -struct lmo_entry { - uint32_t key_id; - uint32_t val_id; - uint32_t offset; - uint32_t length; - struct lmo_entry *next; -} __attribute__((packed)); - -typedef struct lmo_entry lmo_entry_t; - - -struct lmo_archive { - int fd; - uint32_t length; - lmo_entry_t *index; - char *mmap; -}; - -typedef struct lmo_archive lmo_archive_t; - - -uint32_t sfh_hash(const char * data, int len); - -char _lmo_error[1024]; -const char * lmo_error(void); - -lmo_archive_t * lmo_open(const char *file); -int lmo_lookup(lmo_archive_t *ar, const char *key, char *dest, int len); -void lmo_close(lmo_archive_t *ar); - -#endif diff --git a/libs/lmo/src/lmo_core.c b/libs/lmo/src/lmo_core.c deleted file mode 100644 index 08141383e..000000000 --- a/libs/lmo/src/lmo_core.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * lmo - Lua Machine Objects - Base functions - * - * Copyright (C) 2009-2010 Jo-Philipp Wich <xm@subsignal.org> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "lmo.h" - -extern char _lmo_error[1024]; - -static int lmo_read32( int fd, uint32_t *val ) -{ - if( read(fd, val, 4) < 4 ) - return -1; - - *val = ntohl(*val); - - return 4; -} - -static char * error(const char *message, int add_errno) -{ - memset(_lmo_error, 0, sizeof(_lmo_error)); - - if( add_errno ) - snprintf(_lmo_error, sizeof(_lmo_error), - "%s: %s", message, strerror(errno)); - else - snprintf(_lmo_error, sizeof(_lmo_error), "%s", message); - - return NULL; -} - -const char * lmo_error(void) -{ - return _lmo_error; -} - -lmo_archive_t * lmo_open(const char *file) -{ - int in = -1; - uint32_t idx_offset = 0; - uint32_t i; - struct stat s; - - lmo_archive_t *ar = NULL; - lmo_entry_t *head = NULL; - lmo_entry_t *entry = NULL; - - if( stat(file, &s) == -1 ) - { - error("Can not stat file", 1); - goto cleanup; - } - - if( (in = open(file, O_RDONLY)) == -1 ) - { - error("Can not open file", 1); - goto cleanup; - } - - if( lseek(in, -sizeof(uint32_t), SEEK_END) == -1 ) - { - error("Can not seek to eof", 1); - goto cleanup; - } - - if( lmo_read32(in, &idx_offset) != 4 ) - { - error("Unexpected EOF while reading index offset", 0); - goto cleanup; - } - - if( lseek(in, (off_t)idx_offset, SEEK_SET) == -1 ) - { - error("Can not seek to index offset", 1); - goto cleanup; - } - - if( (ar = (lmo_archive_t *) malloc(sizeof(lmo_archive_t))) != NULL ) - { - ar->fd = in; - ar->length = idx_offset; - - fcntl(ar->fd, F_SETFD, fcntl(ar->fd, F_GETFD) | FD_CLOEXEC); - - for( i = idx_offset; - i < (s.st_size - sizeof(uint32_t)); - i += (4 * sizeof(uint32_t)) - ) { - if( (entry = (lmo_entry_t *) malloc(sizeof(lmo_entry_t))) != NULL ) - { - if( (lmo_read32(ar->fd, &entry->key_id) == 4) && - (lmo_read32(ar->fd, &entry->val_id) == 4) && - (lmo_read32(ar->fd, &entry->offset) == 4) && - (lmo_read32(ar->fd, &entry->length) == 4) - ) { - entry->next = head; - head = entry; - } - else - { - error("Unexpected EOF while reading index entry", 0); - goto cleanup; - } - } - else - { - error("Out of memory", 0); - goto cleanup; - } - } - - ar->index = head; - - if( lseek(ar->fd, 0, SEEK_SET) == -1 ) - { - error("Can not seek to start", 1); - goto cleanup; - } - - if( (ar->mmap = mmap(NULL, ar->length, PROT_READ, MAP_PRIVATE, ar->fd, 0)) == MAP_FAILED ) - { - error("Failed to memory map archive contents", 1); - goto cleanup; - } - - return ar; - } - else - { - error("Out of memory", 0); - goto cleanup; - } - - - cleanup: - - if( in > -1 ) - close(in); - - if( head != NULL ) - { - entry = head; - - while( entry != NULL ) - { - head = entry->next; - free(entry); - entry = head; - } - - head = entry = NULL; - } - - if( ar != NULL ) - { - if( (ar->mmap != NULL) && (ar->mmap != MAP_FAILED) ) - munmap(ar->mmap, ar->length); - - free(ar); - ar = NULL; - } - - return NULL; -} - -void lmo_close(lmo_archive_t *ar) -{ - lmo_entry_t *head = NULL; - lmo_entry_t *entry = NULL; - - if( ar != NULL ) - { - entry = ar->index; - - while( entry != NULL ) - { - head = entry->next; - free(entry); - entry = head; - } - - head = entry = NULL; - - if( (ar->mmap != NULL) && (ar->mmap != MAP_FAILED) ) - munmap(ar->mmap, ar->length); - - close(ar->fd); - free(ar); - - ar = NULL; - } -} - -int lmo_lookup(lmo_archive_t *ar, const char *key, char *dest, int len) -{ - uint32_t look_key = sfh_hash(key, strlen(key)); - int copy_len = -1; - lmo_entry_t *entry; - - if( !ar ) - return copy_len; - - entry = ar->index; - - while( entry != NULL ) - { - if( entry->key_id == look_key ) - { - copy_len = ((len - 1) > entry->length) ? entry->length : (len - 1); - memcpy(dest, &ar->mmap[entry->offset], copy_len); - dest[copy_len] = '\0'; - - break; - } - - entry = entry->next; - } - - return copy_len; -} diff --git a/libs/lmo/src/lmo_hash.c b/libs/lmo/src/lmo_hash.c deleted file mode 100644 index bc8e6fe4e..000000000 --- a/libs/lmo/src/lmo_hash.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Hash function from http://www.azillionmonkeys.com/qed/hash.html - * Copyright (C) 2004-2008 by Paul Hsieh - */ - -#include "lmo.h" - -uint32_t sfh_hash(const char * data, int len) -{ - uint32_t hash = len, tmp; - int rem; - - if (len <= 0 || data == NULL) return 0; - - rem = len & 3; - len >>= 2; - - /* Main loop */ - for (;len > 0; len--) { - hash += sfh_get16(data); - tmp = (sfh_get16(data+2) << 11) ^ hash; - hash = (hash << 16) ^ tmp; - data += 2*sizeof(uint16_t); - hash += hash >> 11; - } - - /* Handle end cases */ - switch (rem) { - case 3: hash += sfh_get16(data); - hash ^= hash << 16; - hash ^= data[sizeof(uint16_t)] << 18; - hash += hash >> 11; - break; - case 2: hash += sfh_get16(data); - hash ^= hash << 11; - hash += hash >> 17; - break; - case 1: hash += *data; - hash ^= hash << 10; - hash += hash >> 1; - } - - /* Force "avalanching" of final 127 bits */ - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - - return hash; -} - diff --git a/libs/lmo/src/lmo_lookup.c b/libs/lmo/src/lmo_lookup.c deleted file mode 100644 index 8b48f7fac..000000000 --- a/libs/lmo/src/lmo_lookup.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * lmo - Lua Machine Objects - Lookup utility - * - * Copyright (C) 2009 Jo-Philipp Wich <xm@subsignal.org> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "lmo.h" - -extern char _lmo_error[1024]; - -static void die(const char *msg) -{ - printf("Error: %s\n", msg); - exit(1); -} - -static void usage(const char *name) -{ - printf("Usage: %s input.lmo key\n", name); - exit(1); -} - -int main(int argc, char *argv[]) -{ - char val[4096]; - lmo_archive_t *ar = NULL; - - if( argc != 3 ) - usage(argv[0]); - - if( (ar = (lmo_archive_t *) lmo_open(argv[1])) != NULL ) - { - if( lmo_lookup(ar, argv[2], val, sizeof(val)) > -1 ) - { - printf("%s\n", val); - } - - lmo_close(ar); - } - else - { - die(lmo_error()); - } - - return 0; -} diff --git a/libs/lmo/src/lmo_lualib.c b/libs/lmo/src/lmo_lualib.c deleted file mode 100644 index 5cc1e7d69..000000000 --- a/libs/lmo/src/lmo_lualib.c +++ /dev/null @@ -1,263 +0,0 @@ -/* - * lmo - Lua Machine Objects - Lua binding - * - * Copyright (C) 2009-2012 Jo-Philipp Wich <xm@subsignal.org> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "lmo_lualib.h" - -extern char _lmo_error[1024]; - - -static int lmo_L_open(lua_State *L) { - const char *filename = luaL_checklstring(L, 1, NULL); - lmo_archive_t *ar, **udata; - - if( (ar = lmo_open(filename)) != NULL ) - { - if( (udata = lua_newuserdata(L, sizeof(lmo_archive_t *))) != NULL ) - { - *udata = ar; - luaL_getmetatable(L, LMO_ARCHIVE_META); - lua_setmetatable(L, -2); - return 1; - } - - lmo_close(ar); - lua_pushnil(L); - lua_pushstring(L, "out of memory"); - return 2; - } - - lua_pushnil(L); - lua_pushstring(L, lmo_error()); - return 2; -} - -static uint32_t _lmo_hash_string(lua_State *L, int n) { - size_t len; - const char *str = luaL_checklstring(L, n, &len); - char res[4096]; - char *ptr, prev; - - if (!str || len >= sizeof(res)) - return 0; - - for (prev = ' ', ptr = res; *str; prev = *str, str++) - { - if (isspace(*str)) - { - if (!isspace(prev)) - *ptr++ = ' '; - } - else - { - *ptr++ = *str; - } - } - - if ((ptr > res) && isspace(*(ptr-1))) - ptr--; - - return sfh_hash(res, ptr - res); -} - -static int lmo_L_hash(lua_State *L) { - uint32_t hash = _lmo_hash_string(L, 1); - lua_pushinteger(L, (lua_Integer)hash); - return 1; -} - -static lmo_luaentry_t *_lmo_push_entry(lua_State *L) { - lmo_luaentry_t *le; - - if( (le = lua_newuserdata(L, sizeof(lmo_luaentry_t))) != NULL ) - { - luaL_getmetatable(L, LMO_ENTRY_META); - lua_setmetatable(L, -2); - - return le; - } - - return NULL; -} - -static int _lmo_lookup(lua_State *L, lmo_archive_t *ar, uint32_t hash) { - lmo_entry_t *e = ar->index; - lmo_luaentry_t *le = NULL; - - while( e != NULL ) - { - if( e->key_id == hash ) - { - if( (le = _lmo_push_entry(L)) != NULL ) - { - le->archive = ar; - le->entry = e; - return 1; - } - else - { - lua_pushnil(L); - lua_pushstring(L, "out of memory"); - return 2; - } - } - - e = e->next; - } - - lua_pushnil(L); - return 1; -} - -static int lmo_L_get(lua_State *L) { - lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META); - uint32_t hash = (uint32_t) luaL_checkinteger(L, 2); - return _lmo_lookup(L, *ar, hash); -} - -static int lmo_L_lookup(lua_State *L) { - lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META); - uint32_t hash = _lmo_hash_string(L, 2); - return _lmo_lookup(L, *ar, hash); -} - -static int lmo_L_foreach(lua_State *L) { - lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META); - lmo_entry_t *e = (*ar)->index; - - if( lua_isfunction(L, 2) ) - { - while( e != NULL ) - { - lua_pushvalue(L, 2); - lua_pushinteger(L, e->key_id); - lua_pushlstring(L, &(*ar)->mmap[e->offset], e->length); - lua_pcall(L, 2, 0, 0); - e = e->next; - } - } - - return 0; -} - -static int lmo_L__gc(lua_State *L) { - lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META); - - if( (*ar) != NULL ) - lmo_close(*ar); - - *ar = NULL; - - return 0; -} - -static int lmo_L__tostring(lua_State *L) { - lmo_archive_t **ar = luaL_checkudata(L, 1, LMO_ARCHIVE_META); - lua_pushfstring(L, "LMO Archive (%d bytes)", (*ar)->length); - return 1; -} - - -static int _lmo_convert_entry(lua_State *L, int idx) { - lmo_luaentry_t *le = luaL_checkudata(L, idx, LMO_ENTRY_META); - - lua_pushlstring(L, - &le->archive->mmap[le->entry->offset], - le->entry->length - ); - - return 1; -} - -static int lmo_L_entry__tostring(lua_State *L) { - return _lmo_convert_entry(L, 1); -} - -static int lmo_L_entry__concat(lua_State *L) { - if( lua_isuserdata(L, 1) ) - _lmo_convert_entry(L, 1); - else - lua_pushstring(L, lua_tostring(L, 1)); - - if( lua_isuserdata(L, 2) ) - _lmo_convert_entry(L, 2); - else - lua_pushstring(L, lua_tostring(L, 2)); - - lua_concat(L, 2); - - return 1; -} - -static int lmo_L_entry__len(lua_State *L) { - lmo_luaentry_t *le = luaL_checkudata(L, 1, LMO_ENTRY_META); - lua_pushinteger(L, le->entry->length); - return 1; -} - -static int lmo_L_entry__gc(lua_State *L) { - lmo_luaentry_t *le = luaL_checkudata(L, 1, LMO_ENTRY_META); - le->archive = NULL; - le->entry = NULL; - return 0; -} - - -/* lmo method table */ -static const luaL_reg M[] = { - {"close", lmo_L__gc}, - {"get", lmo_L_get}, - {"lookup", lmo_L_lookup}, - {"foreach", lmo_L_foreach}, - {"__tostring", lmo_L__tostring}, - {"__gc", lmo_L__gc}, - {NULL, NULL} -}; - -/* lmo.entry method table */ -static const luaL_reg E[] = { - {"__tostring", lmo_L_entry__tostring}, - {"__concat", lmo_L_entry__concat}, - {"__len", lmo_L_entry__len}, - {"__gc", lmo_L_entry__gc}, - {NULL, NULL} -}; - -/* module table */ -static const luaL_reg R[] = { - {"open", lmo_L_open}, - {"hash", lmo_L_hash}, - {NULL, NULL} -}; - -LUALIB_API int luaopen_lmo(lua_State *L) { - luaL_newmetatable(L, LMO_ARCHIVE_META); - luaL_register(L, NULL, M); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - lua_setglobal(L, LMO_ARCHIVE_META); - - luaL_newmetatable(L, LMO_ENTRY_META); - luaL_register(L, NULL, E); - lua_pushvalue(L, -1); - lua_setfield(L, -2, "__index"); - lua_setglobal(L, LMO_ENTRY_META); - - luaL_register(L, LMO_LUALIB_META, R); - - return 1; -} diff --git a/libs/lmo/src/lmo_lualib.h b/libs/lmo/src/lmo_lualib.h deleted file mode 100644 index 887889d04..000000000 --- a/libs/lmo/src/lmo_lualib.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * lmo - Lua Machine Objects - Lua library header - * - * Copyright (C) 2009-2012 Jo-Philipp Wich <xm@subsignal.org> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _LMO_LUALIB_H_ -#define _LMO_LUALIB_H_ - -#include <lua.h> -#include <lualib.h> -#include <lauxlib.h> -#include <ctype.h> - -#include "lmo.h" - -#define LMO_LUALIB_META "lmo" -#define LMO_ARCHIVE_META "lmo.archive" -#define LMO_ENTRY_META "lmo.entry" - -struct lmo_luaentry { - lmo_archive_t *archive; - lmo_entry_t *entry; -}; - -typedef struct lmo_luaentry lmo_luaentry_t; - - -LUALIB_API int luaopen_lmo(lua_State *L); - -#endif diff --git a/libs/lmo/src/lmo_po2lmo.c b/libs/lmo/src/lmo_po2lmo.c deleted file mode 100644 index f6f399423..000000000 --- a/libs/lmo/src/lmo_po2lmo.c +++ /dev/null @@ -1,226 +0,0 @@ -/* - * lmo - Lua Machine Objects - PO to LMO conversion tool - * - * Copyright (C) 2009-2011 Jo-Philipp Wich <xm@subsignal.org> - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "lmo.h" - -static void die(const char *msg) -{ - fprintf(stderr, "Error: %s\n", msg); - exit(1); -} - -static void usage(const char *name) -{ - fprintf(stderr, "Usage: %s input.po output.lmo\n", name); - exit(1); -} - -static void print(const void *ptr, size_t size, size_t nmemb, FILE *stream) -{ - if( fwrite(ptr, size, nmemb, stream) == 0 ) - die("Failed to write stdout"); -} - -static int extract_string(const char *src, char *dest, int len) -{ - int pos = 0; - int esc = 0; - int off = -1; - - for( pos = 0; (pos < strlen(src)) && (pos < len); pos++ ) - { - if( (off == -1) && (src[pos] == '"') ) - { - off = pos + 1; - } - else if( off >= 0 ) - { - if( esc == 1 ) - { - switch (src[pos]) - { - case '"': - case '\\': - off++; - break; - } - dest[pos-off] = src[pos]; - esc = 0; - } - else if( src[pos] == '\\' ) - { - dest[pos-off] = src[pos]; - esc = 1; - } - else if( src[pos] != '"' ) - { - dest[pos-off] = src[pos]; - } - else - { - dest[pos-off] = '\0'; - break; - } - } - } - - return (off > -1) ? strlen(dest) : -1; -} - -int main(int argc, char *argv[]) -{ - char line[4096]; - char key[4096]; - char val[4096]; - char tmp[4096]; - int state = 0; - int offset = 0; - int length = 0; - uint32_t key_id, val_id; - - FILE *in; - FILE *out; - - lmo_entry_t *head = NULL; - lmo_entry_t *entry = NULL; - - if( (argc != 3) || ((in = fopen(argv[1], "r")) == NULL) || ((out = fopen(argv[2], "w")) == NULL) ) - usage(argv[0]); - - memset(line, 0, sizeof(key)); - memset(key, 0, sizeof(val)); - memset(val, 0, sizeof(val)); - - while( (NULL != fgets(line, sizeof(line), in)) || (state >= 2 && feof(in)) ) - { - if( state == 0 && strstr(line, "msgid \"") == line ) - { - switch(extract_string(line, key, sizeof(key))) - { - case -1: - die("Syntax error in msgid"); - case 0: - state = 1; - break; - default: - state = 2; - } - } - else if( state == 1 || state == 2 ) - { - if( strstr(line, "msgstr \"") == line || state == 2 ) - { - switch(extract_string(line, val, sizeof(val))) - { - case -1: - state = 4; - break; - default: - state = 3; - } - } - else - { - switch(extract_string(line, tmp, sizeof(tmp))) - { - case -1: - state = 2; - break; - default: - strcat(key, tmp); - } - } - } - else if( state == 3 ) - { - switch(extract_string(line, tmp, sizeof(tmp))) - { - case -1: - state = 4; - break; - default: - strcat(val, tmp); - } - } - - if( state == 4 ) - { - if( strlen(key) > 0 && strlen(val) > 0 ) - { - key_id = sfh_hash(key, strlen(key)); - val_id = sfh_hash(val, strlen(val)); - - if( key_id != val_id ) - { - if( (entry = (lmo_entry_t *) malloc(sizeof(lmo_entry_t))) != NULL ) - { - memset(entry, 0, sizeof(entry)); - length = strlen(val) + ((4 - (strlen(val) % 4)) % 4); - - entry->key_id = htonl(key_id); - entry->val_id = htonl(val_id); - entry->offset = htonl(offset); - entry->length = htonl(strlen(val)); - - print(val, length, 1, out); - offset += length; - - entry->next = head; - head = entry; - } - else - { - die("Out of memory"); - } - } - } - - state = 0; - memset(key, 0, sizeof(key)); - memset(val, 0, sizeof(val)); - } - - memset(line, 0, sizeof(line)); - } - - entry = head; - while( entry != NULL ) - { - print(&entry->key_id, sizeof(uint32_t), 1, out); - print(&entry->val_id, sizeof(uint32_t), 1, out); - print(&entry->offset, sizeof(uint32_t), 1, out); - print(&entry->length, sizeof(uint32_t), 1, out); - entry = entry->next; - } - - if( offset > 0 ) - { - offset = htonl(offset); - print(&offset, sizeof(uint32_t), 1, out); - fsync(fileno(out)); - fclose(out); - } - else - { - fclose(out); - unlink(argv[2]); - } - - fclose(in); - return(0); -} |