gluon-web: import po2lmo tool from luci-base
The code is slightly cleaned up to fix compiler warnings.
This commit is contained in:
parent
911ed5263d
commit
23fd9cd0f9
@ -6,6 +6,7 @@ PKG_VERSION:=1
|
|||||||
PKG_INSTALL:=1
|
PKG_INSTALL:=1
|
||||||
|
|
||||||
include ../gluon.mk
|
include ../gluon.mk
|
||||||
|
include $(INCLUDE_DIR)/host-build.mk
|
||||||
|
|
||||||
define Package/gluon-web
|
define Package/gluon-web
|
||||||
TITLE:=Minimal Lua web framework derived from LuCI
|
TITLE:=Minimal Lua web framework derived from LuCI
|
||||||
@ -24,4 +25,18 @@ define Package/gluon-web/config
|
|||||||
$(foreach lang,$(GLUON_SUPPORTED_LANGS),$(call lang-config,$(lang)))
|
$(foreach lang,$(GLUON_SUPPORTED_LANGS),$(call lang-config,$(lang)))
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
define Host/Prepare
|
||||||
|
$(CP) ./src/* $(HOST_BUILD_DIR)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Host/Compile
|
||||||
|
$(call Host/Compile/Default,gluon-po2lmo)
|
||||||
|
endef
|
||||||
|
|
||||||
|
define Host/Install
|
||||||
|
$(INSTALL_DIR) $(1)/bin
|
||||||
|
$(INSTALL_BIN) $(HOST_BUILD_DIR)/gluon-po2lmo $(1)/bin/
|
||||||
|
endef
|
||||||
|
|
||||||
$(eval $(call BuildPackageGluon,gluon-web))
|
$(eval $(call BuildPackageGluon,gluon-web))
|
||||||
|
$(eval $(call HostBuild))
|
||||||
|
@ -9,6 +9,8 @@ clean:
|
|||||||
parser.so: template_parser.o template_utils.o template_lmo.o template_lualib.o
|
parser.so: template_parser.o template_utils.o template_lmo.o template_lualib.o
|
||||||
$(CC) $(LDFLAGS) -shared -o $@ $^
|
$(CC) $(LDFLAGS) -shared -o $@ $^
|
||||||
|
|
||||||
|
gluon-po2lmo: gluon-po2lmo.o template_lmo.o
|
||||||
|
|
||||||
compile: parser.so
|
compile: parser.so
|
||||||
|
|
||||||
install: compile
|
install: compile
|
||||||
|
256
package/gluon-web/src/gluon-po2lmo.c
Normal file
256
package/gluon-web/src/gluon-po2lmo.c
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
/*
|
||||||
|
* lmo - Lua Machine Objects - PO to LMO conversion tool
|
||||||
|
*
|
||||||
|
* Copyright (C) 2009-2012 Jo-Philipp Wich <jow@openwrt.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 "template_lmo.h"
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
|
__attribute__((noreturn))
|
||||||
|
static void die(const char *msg)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Error: %s\n", msg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((noreturn))
|
||||||
|
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 ssize_t extract_string(const char *src, char *dest, size_t len)
|
||||||
|
{
|
||||||
|
size_t 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) ? (ssize_t) strlen(dest) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmp_index(const void *a, const void *b)
|
||||||
|
{
|
||||||
|
uint32_t x = ((const lmo_entry_t *)a)->key_id;
|
||||||
|
uint32_t y = ((const lmo_entry_t *)b)->key_id;
|
||||||
|
|
||||||
|
if (x < y)
|
||||||
|
return -1;
|
||||||
|
else if (x > y)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_uint32(uint32_t x, FILE *out)
|
||||||
|
{
|
||||||
|
uint32_t y = htonl(x);
|
||||||
|
print(&y, sizeof(uint32_t), 1, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_index(void *array, int n, FILE *out)
|
||||||
|
{
|
||||||
|
lmo_entry_t *e;
|
||||||
|
|
||||||
|
qsort(array, n, sizeof(*e), cmp_index);
|
||||||
|
|
||||||
|
for (e = array; n > 0; n--, e++)
|
||||||
|
{
|
||||||
|
print_uint32(e->key_id, out);
|
||||||
|
print_uint32(e->val_id, out);
|
||||||
|
print_uint32(e->offset, out);
|
||||||
|
print_uint32(e->length, out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
int n_entries = 0;
|
||||||
|
void *array = NULL;
|
||||||
|
lmo_entry_t *entry = NULL;
|
||||||
|
uint32_t key_id, val_id;
|
||||||
|
|
||||||
|
FILE *in;
|
||||||
|
FILE *out;
|
||||||
|
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
n_entries++;
|
||||||
|
array = realloc(array, n_entries * sizeof(lmo_entry_t));
|
||||||
|
entry = (lmo_entry_t *)array + n_entries - 1;
|
||||||
|
|
||||||
|
if (!array)
|
||||||
|
die("Out of memory");
|
||||||
|
|
||||||
|
entry->key_id = key_id;
|
||||||
|
entry->val_id = val_id;
|
||||||
|
entry->offset = offset;
|
||||||
|
entry->length = strlen(val);
|
||||||
|
|
||||||
|
length = strlen(val) + ((4 - (strlen(val) % 4)) % 4);
|
||||||
|
|
||||||
|
print(val, length, 1, out);
|
||||||
|
offset += length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
state = 0;
|
||||||
|
memset(key, 0, sizeof(key));
|
||||||
|
memset(val, 0, sizeof(val));
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(line, 0, sizeof(line));
|
||||||
|
}
|
||||||
|
|
||||||
|
print_index(array, n_entries, out);
|
||||||
|
|
||||||
|
if( offset > 0 )
|
||||||
|
{
|
||||||
|
print_uint32(offset, out);
|
||||||
|
fsync(fileno(out));
|
||||||
|
fclose(out);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fclose(out);
|
||||||
|
unlink(argv[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(in);
|
||||||
|
return(0);
|
||||||
|
}
|
@ -25,20 +25,11 @@
|
|||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
struct lmo_entry {
|
|
||||||
uint32_t key_id;
|
|
||||||
uint32_t val_id;
|
|
||||||
uint32_t offset;
|
|
||||||
uint32_t length;
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
|
|
||||||
static inline uint16_t get_le16(const void *data) {
|
static inline uint16_t get_le16(const void *data) {
|
||||||
const uint8_t *d = data;
|
const uint8_t *d = data;
|
||||||
return (((uint16_t)d[1]) << 8) | d[0];
|
return (((uint16_t)d[1]) << 8) | d[0];
|
||||||
@ -56,7 +47,7 @@ static inline uint32_t get_be32(const void *data) {
|
|||||||
* Hash function from http://www.azillionmonkeys.com/qed/hash.html
|
* Hash function from http://www.azillionmonkeys.com/qed/hash.html
|
||||||
* Copyright (C) 2004-2008 by Paul Hsieh
|
* Copyright (C) 2004-2008 by Paul Hsieh
|
||||||
*/
|
*/
|
||||||
static uint32_t sfh_hash(const void *input, size_t len)
|
uint32_t sfh_hash(const void *input, size_t len)
|
||||||
{
|
{
|
||||||
const uint8_t *data = input;
|
const uint8_t *data = input;
|
||||||
uint32_t hash = len, tmp;
|
uint32_t hash = len, tmp;
|
||||||
|
@ -22,8 +22,15 @@
|
|||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct lmo_entry {
|
||||||
|
uint32_t key_id;
|
||||||
|
uint32_t val_id;
|
||||||
|
uint32_t offset;
|
||||||
|
uint32_t length;
|
||||||
|
} __attribute__((packed));
|
||||||
typedef struct lmo_entry lmo_entry_t;
|
typedef struct lmo_entry lmo_entry_t;
|
||||||
|
|
||||||
|
|
||||||
@ -37,6 +44,8 @@ struct lmo_catalog {
|
|||||||
typedef struct lmo_catalog lmo_catalog_t;
|
typedef struct lmo_catalog lmo_catalog_t;
|
||||||
|
|
||||||
|
|
||||||
|
uint32_t sfh_hash(const void *input, size_t len);
|
||||||
|
|
||||||
bool lmo_load(lmo_catalog_t *cat, const char *file);
|
bool lmo_load(lmo_catalog_t *cat, const char *file);
|
||||||
void lmo_unload(lmo_catalog_t *cat);
|
void lmo_unload(lmo_catalog_t *cat);
|
||||||
bool lmo_translate(const lmo_catalog_t *cat, const char *key, size_t keylen, const char **out, size_t *outlen);
|
bool lmo_translate(const lmo_catalog_t *cat, const char *key, size_t keylen, const char **out, size_t *outlen);
|
||||||
|
@ -31,6 +31,7 @@ GLUON_I18N_CONFIG := $(foreach lang,$(GLUON_SUPPORTED_LANGS),CONFIG_GLUON_WEB_LA
|
|||||||
GLUON_ENABLED_LANGS := en $(foreach lang,$(GLUON_SUPPORTED_LANGS),$(if $(CONFIG_GLUON_WEB_LANG_$(lang)),$(lang)))
|
GLUON_ENABLED_LANGS := en $(foreach lang,$(GLUON_SUPPORTED_LANGS),$(if $(CONFIG_GLUON_WEB_LANG_$(lang)),$(lang)))
|
||||||
|
|
||||||
ifneq ($(wildcard ./i18n/.),)
|
ifneq ($(wildcard ./i18n/.),)
|
||||||
|
PKG_BUILD_DEPENDS += gluon-web/host
|
||||||
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
|
PKG_CONFIG_DEPENDS += $(GLUON_I18N_CONFIG)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
@ -40,7 +41,7 @@ define GluonBuildI18N
|
|||||||
for lang in $$(GLUON_ENABLED_LANGS); do \
|
for lang in $$(GLUON_ENABLED_LANGS); do \
|
||||||
if [ -e $(1)/$$$$lang.po ]; then \
|
if [ -e $(1)/$$$$lang.po ]; then \
|
||||||
rm -f $$(PKG_BUILD_DIR)/i18n/$$$$lang.lmo; \
|
rm -f $$(PKG_BUILD_DIR)/i18n/$$$$lang.lmo; \
|
||||||
po2lmo $(1)/$$$$lang.po $$(PKG_BUILD_DIR)/i18n/$$$$lang.lmo; \
|
gluon-po2lmo $(1)/$$$$lang.po $$(PKG_BUILD_DIR)/i18n/$$$$lang.lmo; \
|
||||||
fi; \
|
fi; \
|
||||||
done
|
done
|
||||||
endef
|
endef
|
||||||
|
Loading…
Reference in New Issue
Block a user