Loading edify/README→edify/README.md +3 −0 Original line number Diff line number Diff line edify ===== Update scripts (from donut onwards) are written in a new little scripting language ("edify") that is superficially somewhat similar to the old one ("amend"). This is a brief overview of the new language. Loading edify/edify_parser.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -45,7 +45,6 @@ static void ExprDump(int depth, const Expr* n, const std::string& script) { int main(int argc, char** argv) { RegisterBuiltins(); FinishRegistration(); if (argc != 2) { printf("Usage: %s <edify script>\n", argv[0]); Loading edify/expr.cpp +13 −52 Original line number Diff line number Diff line Loading @@ -14,20 +14,20 @@ * limitations under the License. */ #include <string.h> #include <stdbool.h> #include "expr.h" #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <unistd.h> #include <string> #include <unordered_map> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include "expr.h" // Functions should: // // - return a malloc()'d string Loading Loading @@ -319,61 +319,22 @@ Value* Literal(const char* name, State* state, int argc, Expr* argv[]) { return StringValue(strdup(name)); } Expr* Build(Function fn, YYLTYPE loc, int count, ...) { va_list v; va_start(v, count); Expr* e = reinterpret_cast<Expr*>(malloc(sizeof(Expr))); e->fn = fn; e->name = "(operator)"; e->argc = count; e->argv = reinterpret_cast<Expr**>(malloc(count * sizeof(Expr*))); int i; for (i = 0; i < count; ++i) { e->argv[i] = va_arg(v, Expr*); } va_end(v); e->start = loc.start; e->end = loc.end; return e; } // ----------------------------------------------------------------- // the function table // ----------------------------------------------------------------- static int fn_entries = 0; static int fn_size = 0; NamedFunction* fn_table = NULL; void RegisterFunction(const char* name, Function fn) { if (fn_entries >= fn_size) { fn_size = fn_size*2 + 1; fn_table = reinterpret_cast<NamedFunction*>(realloc(fn_table, fn_size * sizeof(NamedFunction))); } fn_table[fn_entries].name = name; fn_table[fn_entries].fn = fn; ++fn_entries; } static int fn_entry_compare(const void* a, const void* b) { const char* na = ((const NamedFunction*)a)->name; const char* nb = ((const NamedFunction*)b)->name; return strcmp(na, nb); } static std::unordered_map<std::string, Function> fn_table; void FinishRegistration() { qsort(fn_table, fn_entries, sizeof(NamedFunction), fn_entry_compare); void RegisterFunction(const std::string& name, Function fn) { fn_table[name] = fn; } Function FindFunction(const char* name) { NamedFunction key; key.name = name; NamedFunction* nf = reinterpret_cast<NamedFunction*>(bsearch(&key, fn_table, fn_entries, sizeof(NamedFunction), fn_entry_compare)); if (nf == NULL) { return NULL; Function FindFunction(const std::string& name) { if (fn_table.find(name) == fn_table.end()) { return nullptr; } else { return fn_table[name]; } return nf->fn; } void RegisterBuiltins() { Loading edify/expr.h +7 −33 Original line number Diff line number Diff line Loading @@ -21,11 +21,6 @@ #include <string> #include "error_code.h" #include "yydefs.h" #define MAX_STRING_LEN 1024 typedef struct Expr Expr; struct State { State(const std::string& script, void* cookie); Loading Loading @@ -56,14 +51,15 @@ struct State { #define VAL_STRING 1 // data will be NULL-terminated; size doesn't count null #define VAL_BLOB 2 typedef struct { struct Value { int type; ssize_t size; char* data; } Value; }; struct Expr; typedef Value* (*Function)(const char* name, State* state, int argc, Expr* argv[]); using Function = Value* (*)(const char* name, State* state, int argc, Expr* argv[]); struct Expr { Function fn; Loading Loading @@ -100,43 +96,21 @@ Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]); Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]); Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]); // Convenience function for building expressions with a fixed number // of arguments. Expr* Build(Function fn, YYLTYPE loc, int count, ...); // Global builtins, registered by RegisterBuiltins(). Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]); Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]); Value* AbortFn(const char* name, State* state, 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; } NamedFunction; // Register a new function. The same Function may be registered under // multiple names, but a given name should only be used once. void RegisterFunction(const char* name, Function fn); void RegisterFunction(const std::string& name, Function fn); // Register all the builtins. void RegisterBuiltins(); // Call this after all calls to RegisterFunction() but before parsing // any scripts to finish building the function table. void FinishRegistration(); // Find the Function for a given name; return NULL if no such function // exists. Function FindFunction(const char* name); Function FindFunction(const std::string& name); // --- convenience functions for use in functions --- Loading edify/parser.yy +24 −5 Original line number Diff line number Diff line Loading @@ -33,6 +33,25 @@ struct yy_buffer_state; void yy_switch_to_buffer(struct yy_buffer_state* new_buffer); struct yy_buffer_state* yy_scan_string(const char* yystr); // Convenience function for building expressions with a fixed number // of arguments. static Expr* Build(Function fn, YYLTYPE loc, size_t count, ...) { va_list v; va_start(v, count); Expr* e = static_cast<Expr*>(malloc(sizeof(Expr))); e->fn = fn; e->name = "(operator)"; e->argc = count; e->argv = static_cast<Expr**>(malloc(count * sizeof(Expr*))); for (size_t i = 0; i < count; ++i) { e->argv[i] = va_arg(v, Expr*); } va_end(v); e->start = loc.start; e->end = loc.end; return e; } %} %locations Loading Loading @@ -70,7 +89,7 @@ input: expr { *root = $1; } ; expr: STRING { $$ = reinterpret_cast<Expr*>(malloc(sizeof(Expr))); $$ = static_cast<Expr*>(malloc(sizeof(Expr))); $$->fn = Literal; $$->name = $1; $$->argc = 0; Loading @@ -91,9 +110,9 @@ expr: STRING { | IF expr THEN expr ENDIF { $$ = Build(IfElseFn, @$, 2, $2, $4); } | IF expr THEN expr ELSE expr ENDIF { $$ = Build(IfElseFn, @$, 3, $2, $4, $6); } | STRING '(' arglist ')' { $$ = reinterpret_cast<Expr*>(malloc(sizeof(Expr))); $$ = static_cast<Expr*>(malloc(sizeof(Expr))); $$->fn = FindFunction($1); if ($$->fn == NULL) { if ($$->fn == nullptr) { char buffer[256]; snprintf(buffer, sizeof(buffer), "unknown function \"%s\"", $1); yyerror(root, error_count, buffer); Loading @@ -113,12 +132,12 @@ arglist: /* empty */ { } | expr { $$.argc = 1; $$.argv = reinterpret_cast<Expr**>(malloc(sizeof(Expr*))); $$.argv = static_cast<Expr**>(malloc(sizeof(Expr*))); $$.argv[0] = $1; } | arglist ',' expr { $$.argc = $1.argc + 1; $$.argv = reinterpret_cast<Expr**>(realloc($$.argv, $$.argc * sizeof(Expr*))); $$.argv = static_cast<Expr**>(realloc($$.argv, $$.argc * sizeof(Expr*))); $$.argv[$$.argc-1] = $3; } ; Loading Loading
edify/README→edify/README.md +3 −0 Original line number Diff line number Diff line edify ===== Update scripts (from donut onwards) are written in a new little scripting language ("edify") that is superficially somewhat similar to the old one ("amend"). This is a brief overview of the new language. Loading
edify/edify_parser.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -45,7 +45,6 @@ static void ExprDump(int depth, const Expr* n, const std::string& script) { int main(int argc, char** argv) { RegisterBuiltins(); FinishRegistration(); if (argc != 2) { printf("Usage: %s <edify script>\n", argv[0]); Loading
edify/expr.cpp +13 −52 Original line number Diff line number Diff line Loading @@ -14,20 +14,20 @@ * limitations under the License. */ #include <string.h> #include <stdbool.h> #include "expr.h" #include <stdarg.h> #include <stdio.h> #include <stdlib.h> #include <stdarg.h> #include <string.h> #include <unistd.h> #include <string> #include <unordered_map> #include <android-base/stringprintf.h> #include <android-base/strings.h> #include "expr.h" // Functions should: // // - return a malloc()'d string Loading Loading @@ -319,61 +319,22 @@ Value* Literal(const char* name, State* state, int argc, Expr* argv[]) { return StringValue(strdup(name)); } Expr* Build(Function fn, YYLTYPE loc, int count, ...) { va_list v; va_start(v, count); Expr* e = reinterpret_cast<Expr*>(malloc(sizeof(Expr))); e->fn = fn; e->name = "(operator)"; e->argc = count; e->argv = reinterpret_cast<Expr**>(malloc(count * sizeof(Expr*))); int i; for (i = 0; i < count; ++i) { e->argv[i] = va_arg(v, Expr*); } va_end(v); e->start = loc.start; e->end = loc.end; return e; } // ----------------------------------------------------------------- // the function table // ----------------------------------------------------------------- static int fn_entries = 0; static int fn_size = 0; NamedFunction* fn_table = NULL; void RegisterFunction(const char* name, Function fn) { if (fn_entries >= fn_size) { fn_size = fn_size*2 + 1; fn_table = reinterpret_cast<NamedFunction*>(realloc(fn_table, fn_size * sizeof(NamedFunction))); } fn_table[fn_entries].name = name; fn_table[fn_entries].fn = fn; ++fn_entries; } static int fn_entry_compare(const void* a, const void* b) { const char* na = ((const NamedFunction*)a)->name; const char* nb = ((const NamedFunction*)b)->name; return strcmp(na, nb); } static std::unordered_map<std::string, Function> fn_table; void FinishRegistration() { qsort(fn_table, fn_entries, sizeof(NamedFunction), fn_entry_compare); void RegisterFunction(const std::string& name, Function fn) { fn_table[name] = fn; } Function FindFunction(const char* name) { NamedFunction key; key.name = name; NamedFunction* nf = reinterpret_cast<NamedFunction*>(bsearch(&key, fn_table, fn_entries, sizeof(NamedFunction), fn_entry_compare)); if (nf == NULL) { return NULL; Function FindFunction(const std::string& name) { if (fn_table.find(name) == fn_table.end()) { return nullptr; } else { return fn_table[name]; } return nf->fn; } void RegisterBuiltins() { Loading
edify/expr.h +7 −33 Original line number Diff line number Diff line Loading @@ -21,11 +21,6 @@ #include <string> #include "error_code.h" #include "yydefs.h" #define MAX_STRING_LEN 1024 typedef struct Expr Expr; struct State { State(const std::string& script, void* cookie); Loading Loading @@ -56,14 +51,15 @@ struct State { #define VAL_STRING 1 // data will be NULL-terminated; size doesn't count null #define VAL_BLOB 2 typedef struct { struct Value { int type; ssize_t size; char* data; } Value; }; struct Expr; typedef Value* (*Function)(const char* name, State* state, int argc, Expr* argv[]); using Function = Value* (*)(const char* name, State* state, int argc, Expr* argv[]); struct Expr { Function fn; Loading Loading @@ -100,43 +96,21 @@ Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]); Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]); Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]); // Convenience function for building expressions with a fixed number // of arguments. Expr* Build(Function fn, YYLTYPE loc, int count, ...); // Global builtins, registered by RegisterBuiltins(). Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]); Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]); Value* AbortFn(const char* name, State* state, 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; } NamedFunction; // Register a new function. The same Function may be registered under // multiple names, but a given name should only be used once. void RegisterFunction(const char* name, Function fn); void RegisterFunction(const std::string& name, Function fn); // Register all the builtins. void RegisterBuiltins(); // Call this after all calls to RegisterFunction() but before parsing // any scripts to finish building the function table. void FinishRegistration(); // Find the Function for a given name; return NULL if no such function // exists. Function FindFunction(const char* name); Function FindFunction(const std::string& name); // --- convenience functions for use in functions --- Loading
edify/parser.yy +24 −5 Original line number Diff line number Diff line Loading @@ -33,6 +33,25 @@ struct yy_buffer_state; void yy_switch_to_buffer(struct yy_buffer_state* new_buffer); struct yy_buffer_state* yy_scan_string(const char* yystr); // Convenience function for building expressions with a fixed number // of arguments. static Expr* Build(Function fn, YYLTYPE loc, size_t count, ...) { va_list v; va_start(v, count); Expr* e = static_cast<Expr*>(malloc(sizeof(Expr))); e->fn = fn; e->name = "(operator)"; e->argc = count; e->argv = static_cast<Expr**>(malloc(count * sizeof(Expr*))); for (size_t i = 0; i < count; ++i) { e->argv[i] = va_arg(v, Expr*); } va_end(v); e->start = loc.start; e->end = loc.end; return e; } %} %locations Loading Loading @@ -70,7 +89,7 @@ input: expr { *root = $1; } ; expr: STRING { $$ = reinterpret_cast<Expr*>(malloc(sizeof(Expr))); $$ = static_cast<Expr*>(malloc(sizeof(Expr))); $$->fn = Literal; $$->name = $1; $$->argc = 0; Loading @@ -91,9 +110,9 @@ expr: STRING { | IF expr THEN expr ENDIF { $$ = Build(IfElseFn, @$, 2, $2, $4); } | IF expr THEN expr ELSE expr ENDIF { $$ = Build(IfElseFn, @$, 3, $2, $4, $6); } | STRING '(' arglist ')' { $$ = reinterpret_cast<Expr*>(malloc(sizeof(Expr))); $$ = static_cast<Expr*>(malloc(sizeof(Expr))); $$->fn = FindFunction($1); if ($$->fn == NULL) { if ($$->fn == nullptr) { char buffer[256]; snprintf(buffer, sizeof(buffer), "unknown function \"%s\"", $1); yyerror(root, error_count, buffer); Loading @@ -113,12 +132,12 @@ arglist: /* empty */ { } | expr { $$.argc = 1; $$.argv = reinterpret_cast<Expr**>(malloc(sizeof(Expr*))); $$.argv = static_cast<Expr**>(malloc(sizeof(Expr*))); $$.argv[0] = $1; } | arglist ',' expr { $$.argc = $1.argc + 1; $$.argv = reinterpret_cast<Expr**>(realloc($$.argv, $$.argc * sizeof(Expr*))); $$.argv = static_cast<Expr**>(realloc($$.argv, $$.argc * sizeof(Expr*))); $$.argv[$$.argc-1] = $3; } ; Loading