Skip to content
Snippets Groups Projects
Commit d345a9aa authored by Timo Teräs's avatar Timo Teräs
Browse files

adbgen: split adbgen specific code to separate file

- move adb_walk_text
- move serialize_adb

both are intended only for adbgen which is basically a debugging
applet
parent 91dc10b1
No related branches found
No related tags found
No related merge requests found
......@@ -21,7 +21,7 @@ ZLIB_LIBS := $(shell $(PKG_CONFIG) --libs zlib)
libapk_soname := $(SO_VERSION)
libapk_so := $(obj)/libapk.so.$(libapk_soname)
libapk.so.$(libapk_soname)-objs := \
adb.o adb_comp.o adb_walk_adb.o adb_walk_text.o apk_adb.o \
adb.o adb_comp.o adb_walk_adb.o apk_adb.o \
atom.o balloc.o blob.o commit.o common.o context.o crypto.o crypto_$(CRYPTO).o ctype.o \
database.o hash.o extract_v2.o extract_v3.o fs_fsys.o fs_uvol.o \
io.o io_gunzip.o io_url_$(URL_BACKEND).o tar.o package.o pathbuilder.o print.o process.o \
......@@ -61,11 +61,11 @@ apk-static-libs := $(libapk.a-libs) $(obj)/libapk.a
# Apk utility
progs-y += apk
apk-objs := \
apk.o app_adbdump.o app_adbsign.o app_add.o app_audit.o app_cache.o \
apk.o app_adbdump.o app_adbgen.o app_adbsign.o app_add.o app_audit.o app_cache.o \
app_convdb.o app_convndx.o app_del.o app_dot.o app_extract.o app_fetch.o \
app_fix.o app_index.o app_info.o app_list.o app_manifest.o app_mkndx.o \
app_mkpkg.o app_policy.o app_update.o app_upgrade.o app_search.o \
app_stats.o app_verify.o app_version.o applet.o serialize_adb.o
app_stats.o app_verify.o app_version.o applet.o
LIBS_apk := -lapk
LIBS_apk.so := -L$(obj) -lapk
......
......@@ -294,7 +294,6 @@ extern const struct adb_db_schema adb_all_schemas[];
extern const struct apk_serializer_ops apk_serializer_adb;
int adb_walk_adb(struct apk_istream *is, struct apk_ostream *os, const struct apk_serializer_ops *ser, struct apk_trust *trust);
int adb_walk_text(struct apk_istream *is, struct apk_ostream *os, const struct apk_serializer_ops *ser, struct apk_trust *trust);
// Seamless compression support
......
#include <errno.h>
#include "adb.h"
//#define DEBUG_PRINT
#ifdef DEBUG_PRINT
#include <stdio.h>
#define dbg_printf(args...) fprintf(stderr, args)
#else
#define dbg_printf(args...)
#endif
int adb_walk_text(struct apk_istream *is, struct apk_ostream *os, const struct apk_serializer_ops *ops, struct apk_trust *trust)
{
const apk_blob_t token = APK_BLOB_STR("\n");
const apk_blob_t comment = APK_BLOB_STR(" #");
const apk_blob_t key_sep = APK_BLOB_STR(": ");
struct apk_serializer *ser;
char mblockdata[1024*4];
apk_blob_t l, comm, mblock = APK_BLOB_BUF(mblockdata);
int r = 0, i, multi_line = 0, nesting = 0, new_item = 0;
uint8_t started[64] = {0};
ser = apk_serializer_init_alloca(ops, os);
if (IS_ERR(ser)) {
if (IS_ERR(is)) apk_istream_close(is);
return PTR_ERR(ser);
}
if (IS_ERR(is)) {
r = PTR_ERR(is);
goto err;
}
ser->trust = trust;
if (apk_istream_get_delim(is, token, &l) != 0) goto err;
if (!apk_blob_pull_blob_match(&l, APK_BLOB_STR("#%SCHEMA: "))) goto err;
if ((r = apk_ser_start_schema(ser, apk_blob_pull_uint(&l, 16))) != 0) goto err;
started[0] = 1;
while (apk_istream_get_delim(is, token, &l) == 0) {
for (i = 0; l.len >= 2 && l.ptr[0] == ' ' && l.ptr[1] == ' '; i++, l.ptr += 2, l.len -= 2)
if (multi_line && i >= multi_line) break;
for (; nesting > i; nesting--) {
if (multi_line) {
apk_blob_t data = apk_blob_pushed(APK_BLOB_BUF(mblockdata), mblock);
if (APK_BLOB_IS_NULL(data)) {
r = -E2BIG;
goto err;
}
if (data.len && data.ptr[data.len-1] == '\n') data.len--;
dbg_printf("Multiline-Scalar >%d> "BLOB_FMT"\n", nesting, BLOB_PRINTF(data));
if ((r = apk_ser_string_ml(ser, data, 1)) != 0) goto err;
mblock = APK_BLOB_BUF(mblockdata);
multi_line = 0;
}
if (started[nesting]) {
dbg_printf("End %d\n", nesting);
if ((r = apk_ser_end(ser)) != 0) goto err;
}
}
if (l.len >= 2 && l.ptr[0] == '-' && l.ptr[1] == ' ') {
l.ptr += 2, l.len -= 2;
if (!started[nesting]) {
dbg_printf("Array %d\n", nesting);
if ((r = apk_ser_start_array(ser, 0)) != 0) goto err;
started[nesting] = 1;
}
new_item = 1;
}
dbg_printf(" >%d/%d< >"BLOB_FMT"<\n", nesting, i, BLOB_PRINTF(l));
if (multi_line) {
dbg_printf("Scalar-Block:>%d> "BLOB_FMT"\n", nesting, BLOB_PRINTF(l));
apk_blob_push_blob(&mblock, l);
apk_blob_push_blob(&mblock, APK_BLOB_STR("\n"));
new_item = 0;
continue;
}
if (l.len && l.ptr[0] == '#') {
if ((r = apk_ser_comment(ser, l)) != 0) goto err;
continue;
}
// contains ' #' -> comment
if (!apk_blob_split(l, comment, &l, &comm))
comm.len = 0;
if (l.len) {
apk_blob_t key = APK_BLOB_NULL, scalar = APK_BLOB_NULL;
int start = 0;
if (apk_blob_split(l, key_sep, &key, &scalar)) {
// contains ': ' -> key + scalar
} else if (l.ptr[l.len-1] == ':') {
// ends ':' -> key + indented object/array
key = APK_BLOB_PTR_LEN(l.ptr, l.len-1);
start = 1;
} else {
scalar = l;
}
if (key.len) {
if (new_item) {
started[++nesting] = 0;
dbg_printf("Array-Object %d\n", nesting);
}
if (!started[nesting]) {
dbg_printf("Object %d\n", nesting);
if ((r = apk_ser_start_object(ser)) != 0) goto err;
started[nesting] = 1;
}
dbg_printf("Key >%d> "BLOB_FMT"\n", nesting, BLOB_PRINTF(key));
if ((r = apk_ser_key(ser, key)) != 0) goto err;
if (start) started[++nesting] = 0;
}
if (scalar.len) {
if (scalar.ptr[0] == '|') {
dbg_printf("Scalar-block >%d> "BLOB_FMT"\n", nesting, BLOB_PRINTF(scalar));
// scalar '|' -> starts string literal block
started[++nesting] = 0;
multi_line = nesting;
} else {
if (scalar.ptr[0] == '\'') {
dbg_printf("Scalar-squote >%d> "BLOB_FMT"\n", nesting, BLOB_PRINTF(scalar));
if (scalar.len < 2 || scalar.ptr[scalar.len-1] != '\'') {
r = -APKE_FORMAT_INVALID;
goto err;
}
scalar.ptr ++;
scalar.len -= 2;
} else {
dbg_printf("Scalar >%d> "BLOB_FMT"\n", nesting, BLOB_PRINTF(scalar));
}
if ((r = apk_ser_string(ser, scalar)) != 0) goto err;
}
}
new_item = 0;
}
if (comm.len) {
if ((r = apk_ser_comment(ser, comm)) != 0) goto err;
}
dbg_printf(">%d> "BLOB_FMT"\n", nesting, BLOB_PRINTF(l));
}
apk_ser_end(ser);
err:
apk_serializer_cleanup(ser);
return apk_istream_close_error(is, r);
}
......@@ -63,30 +63,3 @@ static struct apk_applet apk_adbdump = {
.main = adbdump_main,
};
APK_DEFINE_APPLET(apk_adbdump);
static int adbgen_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args)
{
struct apk_out *out = &ac->out;
apk_array_foreach_item(arg, args) {
int r = adb_walk_text(
apk_istream_from_file(AT_FDCWD, arg),
apk_ostream_to_fd(STDOUT_FILENO),
&apk_serializer_adb,
apk_ctx_get_trust(ac));
if (r) {
apk_err(out, "%s: %s", arg, apk_error_str(r));
return r;
}
}
return 0;
}
static struct apk_applet apk_adbgen = {
.name = "adbgen",
.main = adbgen_main,
};
APK_DEFINE_APPLET(apk_adbgen);
#include <errno.h>
#include <unistd.h>
#include "adb.h"
#include "apk_adb.h"
#include "apk_applet.h"
#include "apk_print.h"
//#define DEBUG_PRINT
#ifdef DEBUG_PRINT
#include <stdio.h>
#define dbg_printf(args...) fprintf(stderr, args)
#else
#define dbg_printf(args...)
#endif
#define SERIALIZE_ADB_MAX_IDB 2
#define SERIALIZE_ADB_MAX_VALUES 100000
......@@ -166,3 +178,171 @@ const struct apk_serializer_ops apk_serializer_adb = {
.key = ser_adb_key,
.string = ser_adb_string,
};
static int adb_walk_yaml(struct apk_istream *is, struct apk_ostream *os, const struct apk_serializer_ops *ops, struct apk_trust *trust)
{
const apk_blob_t token = APK_BLOB_STR("\n");
const apk_blob_t comment = APK_BLOB_STR(" #");
const apk_blob_t key_sep = APK_BLOB_STR(": ");
struct apk_serializer *ser;
char mblockdata[1024*4];
apk_blob_t l, comm, mblock = APK_BLOB_BUF(mblockdata);
int r = 0, i, multi_line = 0, nesting = 0, new_item = 0;
uint8_t started[64] = {0};
ser = apk_serializer_init_alloca(ops, os);
if (IS_ERR(ser)) {
if (IS_ERR(is)) apk_istream_close(is);
return PTR_ERR(ser);
}
if (IS_ERR(is)) {
r = PTR_ERR(is);
goto err;
}
ser->trust = trust;
if (apk_istream_get_delim(is, token, &l) != 0) goto err;
if (!apk_blob_pull_blob_match(&l, APK_BLOB_STR("#%SCHEMA: "))) goto err;
if ((r = apk_ser_start_schema(ser, apk_blob_pull_uint(&l, 16))) != 0) goto err;
started[0] = 1;
while (apk_istream_get_delim(is, token, &l) == 0) {
for (i = 0; l.len >= 2 && l.ptr[0] == ' ' && l.ptr[1] == ' '; i++, l.ptr += 2, l.len -= 2)
if (multi_line && i >= multi_line) break;
for (; nesting > i; nesting--) {
if (multi_line) {
apk_blob_t data = apk_blob_pushed(APK_BLOB_BUF(mblockdata), mblock);
if (APK_BLOB_IS_NULL(data)) {
r = -E2BIG;
goto err;
}
if (data.len && data.ptr[data.len-1] == '\n') data.len--;
dbg_printf("Multiline-Scalar >%d> "BLOB_FMT"\n", nesting, BLOB_PRINTF(data));
if ((r = apk_ser_string_ml(ser, data, 1)) != 0) goto err;
mblock = APK_BLOB_BUF(mblockdata);
multi_line = 0;
}
if (started[nesting]) {
dbg_printf("End %d\n", nesting);
if ((r = apk_ser_end(ser)) != 0) goto err;
}
}
if (l.len >= 2 && l.ptr[0] == '-' && l.ptr[1] == ' ') {
l.ptr += 2, l.len -= 2;
if (!started[nesting]) {
dbg_printf("Array %d\n", nesting);
if ((r = apk_ser_start_array(ser, 0)) != 0) goto err;
started[nesting] = 1;
}
new_item = 1;
}
dbg_printf(" >%d/%d< >"BLOB_FMT"<\n", nesting, i, BLOB_PRINTF(l));
if (multi_line) {
dbg_printf("Scalar-Block:>%d> "BLOB_FMT"\n", nesting, BLOB_PRINTF(l));
apk_blob_push_blob(&mblock, l);
apk_blob_push_blob(&mblock, APK_BLOB_STR("\n"));
new_item = 0;
continue;
}
if (l.len && l.ptr[0] == '#') {
if ((r = apk_ser_comment(ser, l)) != 0) goto err;
continue;
}
// contains ' #' -> comment
if (!apk_blob_split(l, comment, &l, &comm))
comm.len = 0;
if (l.len) {
apk_blob_t key = APK_BLOB_NULL, scalar = APK_BLOB_NULL;
int start = 0;
if (apk_blob_split(l, key_sep, &key, &scalar)) {
// contains ': ' -> key + scalar
} else if (l.ptr[l.len-1] == ':') {
// ends ':' -> key + indented object/array
key = APK_BLOB_PTR_LEN(l.ptr, l.len-1);
start = 1;
} else {
scalar = l;
}
if (key.len) {
if (new_item) {
started[++nesting] = 0;
dbg_printf("Array-Object %d\n", nesting);
}
if (!started[nesting]) {
dbg_printf("Object %d\n", nesting);
if ((r = apk_ser_start_object(ser)) != 0) goto err;
started[nesting] = 1;
}
dbg_printf("Key >%d> "BLOB_FMT"\n", nesting, BLOB_PRINTF(key));
if ((r = apk_ser_key(ser, key)) != 0) goto err;
if (start) started[++nesting] = 0;
}
if (scalar.len) {
if (scalar.ptr[0] == '|') {
dbg_printf("Scalar-block >%d> "BLOB_FMT"\n", nesting, BLOB_PRINTF(scalar));
// scalar '|' -> starts string literal block
started[++nesting] = 0;
multi_line = nesting;
} else {
if (scalar.ptr[0] == '\'') {
dbg_printf("Scalar-squote >%d> "BLOB_FMT"\n", nesting, BLOB_PRINTF(scalar));
if (scalar.len < 2 || scalar.ptr[scalar.len-1] != '\'') {
r = -APKE_FORMAT_INVALID;
goto err;
}
scalar.ptr ++;
scalar.len -= 2;
} else {
dbg_printf("Scalar >%d> "BLOB_FMT"\n", nesting, BLOB_PRINTF(scalar));
}
if ((r = apk_ser_string(ser, scalar)) != 0) goto err;
}
}
new_item = 0;
}
if (comm.len) {
if ((r = apk_ser_comment(ser, comm)) != 0) goto err;
}
dbg_printf(">%d> "BLOB_FMT"\n", nesting, BLOB_PRINTF(l));
}
apk_ser_end(ser);
err:
apk_serializer_cleanup(ser);
return apk_istream_close_error(is, r);
}
static int adbgen_main(void *pctx, struct apk_ctx *ac, struct apk_string_array *args)
{
struct apk_out *out = &ac->out;
apk_array_foreach_item(arg, args) {
int r = adb_walk_yaml(
apk_istream_from_file(AT_FDCWD, arg),
apk_ostream_to_fd(STDOUT_FILENO),
&apk_serializer_adb,
apk_ctx_get_trust(ac));
if (r) {
apk_err(out, "%s: %s", arg, apk_error_str(r));
return r;
}
}
return 0;
}
static struct apk_applet apk_adbgen = {
.name = "adbgen",
.main = adbgen_main,
};
APK_DEFINE_APPLET(apk_adbgen);
......@@ -6,7 +6,6 @@ libapk_src = [
'adb.c',
'adb_comp.c',
'adb_walk_adb.c',
'adb_walk_text.c',
'apk_adb.c',
'atom.c',
'balloc.c',
......@@ -70,6 +69,7 @@ libapk_headers = [
apk_src = [
'apk.c',
'app_adbdump.c',
'app_adbgen.c',
'app_adbsign.c',
'app_add.c',
'app_audit.c',
......@@ -95,7 +95,6 @@ apk_src = [
'app_verify.c',
'app_version.c',
'applet.c',
'serialize_adb.c',
]
apk_cargs = [
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment