summaryrefslogtreecommitdiffstats
path: root/edify
diff options
context:
space:
mode:
authorDoug Zongker <dougz@android.com>2009-06-10 14:11:53 -0700
committerDoug Zongker <dougz@android.com>2009-06-11 16:25:29 -0700
commit9931f7f3c1288171319e9ff7d053ebaad07db720 (patch)
tree42ae5b40309f6ea3410c5ad496f81368675274f7 /edify
parent9b9c2114bd7d02200ce43cb9ec513473079dfad9 (diff)
downloadbootable_recovery-9931f7f3c1288171319e9ff7d053ebaad07db720.zip
bootable_recovery-9931f7f3c1288171319e9ff7d053ebaad07db720.tar.gz
bootable_recovery-9931f7f3c1288171319e9ff7d053ebaad07db720.tar.bz2
edify extensions for OTA package installation, part 1
Adds the following edify functions: mount unmount format show_progress delete delete_recursive package_extract symlink set_perm set_perm_recursive This set is enough to extract and install the system part of a (full) OTA package. Adds the updater binary that extracts an edify script from the OTA package and then executes it. Minor changes to the edify core (adds a sleep() builtin for debugging, adds "." to the set of characters that can appear in an unquoted string).
Diffstat (limited to 'edify')
-rw-r--r--edify/Android.mk17
-rw-r--r--edify/README2
-rw-r--r--edify/expr.c95
-rw-r--r--edify/expr.h23
-rw-r--r--edify/lexer.l2
-rw-r--r--edify/main.c9
6 files changed, 136 insertions, 12 deletions
diff --git a/edify/Android.mk b/edify/Android.mk
index 803fba2..fac0ba7 100644
--- a/edify/Android.mk
+++ b/edify/Android.mk
@@ -26,15 +26,14 @@ LOCAL_YACCFLAGS := -v
include $(BUILD_HOST_EXECUTABLE)
-# #
-# # Build the device-side library
-# #
-# include $(CLEAR_VARS)
+#
+# Build the device-side library
+#
+include $(CLEAR_VARS)
-# LOCAL_SRC_FILES := $(edify_src_files)
-# LOCAL_SRC_FILES += $(edify_test_files)
+LOCAL_SRC_FILES := $(edify_src_files)
-# LOCAL_CFLAGS := $(edify_cflags)
-# LOCAL_MODULE := libedify
+LOCAL_CFLAGS := $(edify_cflags)
+LOCAL_MODULE := libedify
-# include $(BUILD_STATIC_LIBRARY)
+include $(BUILD_STATIC_LIBRARY)
diff --git a/edify/README b/edify/README
index 5ccb582..810455c 100644
--- a/edify/README
+++ b/edify/README
@@ -10,7 +10,7 @@ the old one ("amend"). This is a brief overview of the new language.
understood, as are hexadecimal escapes like \x4a.
- String literals consisting of only letters, numbers, colons,
- underscores, and slashes don't need to be in double quotes.
+ underscores, slashes, and periods don't need to be in double quotes.
- The following words are reserved:
diff --git a/edify/expr.c b/edify/expr.c
index b3b8927..129fbd9 100644
--- a/edify/expr.c
+++ b/edify/expr.c
@@ -19,6 +19,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
+#include <unistd.h>
#include "expr.h"
@@ -92,6 +93,12 @@ char* IfElseFn(const char* name, void* cookie, int argc, Expr* argv[]) {
}
char* AbortFn(const char* name, void* cookie, int argc, Expr* argv[]) {
+ char* msg = NULL;
+ if (argc > 0) {
+ msg = Evaluate(cookie, argv[0]);
+ }
+ SetError(msg == NULL ? "called abort()" : msg);
+ free(msg);
return NULL;
}
@@ -105,12 +112,23 @@ char* AssertFn(const char* name, void* cookie, int argc, Expr* argv[]) {
int b = BooleanString(v);
free(v);
if (!b) {
+ SetError("assert() failed");
return NULL;
}
}
return strdup("");
}
+char* SleepFn(const char* name, void* cookie, int argc, Expr* argv[]) {
+ char* val = Evaluate(cookie, argv[0]);
+ if (val == NULL) {
+ return NULL;
+ }
+ int v = strtol(val, NULL, 10);
+ sleep(v);
+ return val;
+}
+
char* PrintFn(const char* name, void* cookie, int argc, Expr* argv[]) {
int i;
for (i = 0; i < argc; ++i) {
@@ -234,6 +252,32 @@ Expr* Build(Function fn, int count, ...) {
return e;
}
+// -----------------------------------------------------------------
+// error reporting
+// -----------------------------------------------------------------
+
+static char* error_message = NULL;
+
+void SetError(const char* message) {
+ if (error_message) {
+ free(error_message);
+ }
+ error_message = strdup(message);
+}
+
+const char* GetError() {
+ return error_message;
+}
+
+void ClearError() {
+ free(error_message);
+ error_message = NULL;
+}
+
+// -----------------------------------------------------------------
+// the function table
+// -----------------------------------------------------------------
+
static int fn_entries = 0;
static int fn_size = 0;
NamedFunction* fn_table = NULL;
@@ -276,4 +320,55 @@ void RegisterBuiltins() {
RegisterFunction("concat", ConcatFn);
RegisterFunction("is_substring", SubstringFn);
RegisterFunction("print", PrintFn);
+ RegisterFunction("sleep", SleepFn);
+}
+
+
+// -----------------------------------------------------------------
+// convenience methods for functions
+// -----------------------------------------------------------------
+
+// Evaluate the expressions in argv, giving 'count' char* (the ... is
+// zero or more char** to put them in). If any expression evaluates
+// to NULL, free the rest and return -1. Return 0 on success.
+int ReadArgs(void* cookie, Expr* argv[], int count, ...) {
+ char** args = malloc(count * sizeof(char*));
+ va_list v;
+ va_start(v, count);
+ int i;
+ for (i = 0; i < count; ++i) {
+ args[i] = Evaluate(cookie, argv[i]);
+ if (args[i] == NULL) {
+ va_end(v);
+ int j;
+ for (j = 0; j < i; ++j) {
+ free(args[j]);
+ }
+ return -1;
+ }
+ *(va_arg(v, char**)) = args[i];
+ }
+ va_end(v);
+ return 0;
+}
+
+// Evaluate the expressions in argv, returning an array of char*
+// results. If any evaluate to NULL, free the rest and return NULL.
+// The caller is responsible for freeing the returned array and the
+// strings it contains.
+char** ReadVarArgs(void* cookie, int argc, Expr* argv[]) {
+ char** args = (char**)malloc(argc * sizeof(char*));
+ int i = 0;
+ for (i = 0; i < argc; ++i) {
+ args[i] = Evaluate(cookie, argv[i]);
+ if (args[i] == NULL) {
+ int j;
+ for (j = 0; j < i; ++j) {
+ free(args[j]);
+ }
+ free(args);
+ return NULL;
+ }
+ }
+ return args;
}
diff --git a/edify/expr.h b/edify/expr.h
index ac5df18..cfbef90 100644
--- a/edify/expr.h
+++ b/edify/expr.h
@@ -57,6 +57,14 @@ char* IfElseFn(const char* name, void* cookie, int argc, Expr* argv[]);
char* AssertFn(const char* name, void* cookie, int argc, Expr* argv[]);
char* AbortFn(const char* name, void* cookie, int argc, Expr* argv[]);
+
+// For setting and getting the global error string (when returning
+// NULL from a function).
+void SetError(const char* message); // makes a copy
+const char* GetError(); // retains ownership
+void ClearError();
+
+
typedef struct {
const char* name;
Function fn;
@@ -77,4 +85,19 @@ void FinishRegistration();
// exists.
Function FindFunction(const char* name);
+
+// --- convenience functions for use in functions ---
+
+// Evaluate the expressions in argv, giving 'count' char* (the ... is
+// zero or more char** to put them in). If any expression evaluates
+// to NULL, free the rest and return -1. Return 0 on success.
+int ReadArgs(void* cookie, Expr* argv[], int count, ...);
+
+// Evaluate the expressions in argv, returning an array of char*
+// results. If any evaluate to NULL, free the rest and return NULL.
+// The caller is responsible for freeing the returned array and the
+// strings it contains.
+char** ReadVarArgs(void* cookie, int argc, Expr* argv[]);
+
+
#endif // _EXPRESSION_H
diff --git a/edify/lexer.l b/edify/lexer.l
index 4faef5d..cb5eb31 100644
--- a/edify/lexer.l
+++ b/edify/lexer.l
@@ -77,7 +77,7 @@ then { gColumn += yyleng; return THEN; }
else { gColumn += yyleng; return ELSE; }
endif { gColumn += yyleng; return ENDIF; }
-[a-zA-Z0-9_:/]+ {
+[a-zA-Z0-9_:/.]+ {
gColumn += yyleng;
yylval.str = strdup(yytext);
return STRING;
diff --git a/edify/main.c b/edify/main.c
index 4d65da2..c959683 100644
--- a/edify/main.c
+++ b/edify/main.c
@@ -158,7 +158,14 @@ int main(int argc, char** argv) {
printf("parse returned %d\n", error);
if (error == 0) {
char* result = Evaluate(NULL, root);
- printf("result is [%s]\n", result == NULL ? "(NULL)" : result);
+ if (result == NULL) {
+ char* errmsg = GetError();
+ printf("result was NULL, message is: %s\n",
+ (errmsg == NULL ? "(NULL)" : errmsg));
+ ClearError();
+ } else {
+ printf("result is [%s]\n", result);
+ }
}
return 0;
}