reconcile korg/master into goog/master
diff --git a/Android.mk b/Android.mk
index 0367fef..deec80a 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1,15 +1,14 @@
+ifneq ($(TARGET_SIMULATOR),true)
+ifeq ($(TARGET_ARCH),arm)
+
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
commands_recovery_local_path := $(LOCAL_PATH)
-ifneq ($(TARGET_SIMULATOR),true)
-ifeq ($(TARGET_ARCH),arm)
-
LOCAL_SRC_FILES := \
recovery.c \
bootloader.c \
- commands.c \
firmware.c \
install.c \
roots.c \
@@ -32,14 +31,19 @@
LOCAL_MODULE_TAGS := eng
-LOCAL_STATIC_LIBRARIES := libminzip libunz libamend libmtdutils libmincrypt
+LOCAL_STATIC_LIBRARIES :=
+ifeq ($(TARGET_RECOVERY_UI_LIB),)
+ LOCAL_SRC_FILES += default_recovery_ui.c
+else
+ LOCAL_STATIC_LIBRARIES += $(TARGET_RECOVERY_UI_LIB)
+endif
+LOCAL_STATIC_LIBRARIES += libminzip libunz libmtdutils libmincrypt
LOCAL_STATIC_LIBRARIES += libminui libpixelflinger_static libpng libcutils
LOCAL_STATIC_LIBRARIES += libstdc++ libc
include $(BUILD_EXECUTABLE)
include $(commands_recovery_local_path)/minui/Android.mk
-include $(commands_recovery_local_path)/amend/Android.mk
include $(commands_recovery_local_path)/minzip/Android.mk
include $(commands_recovery_local_path)/mtdutils/Android.mk
include $(commands_recovery_local_path)/tools/Android.mk
diff --git a/amend/Android.mk b/amend/Android.mk
deleted file mode 100644
index c3b7c32..0000000
--- a/amend/Android.mk
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright 2007 The Android Open Source Project
-#
-
-LOCAL_PATH := $(call my-dir)
-
-amend_src_files := \
- amend.c \
- lexer.l \
- parser_y.y \
- ast.c \
- symtab.c \
- commands.c \
- execute.c
-
-amend_test_files := \
- test_symtab.c \
- test_commands.c
-
-# "-x c" forces the lex/yacc files to be compiled as c;
-# the build system otherwise forces them to be c++.
-amend_cflags := -Wall -x c
-
-#
-# Build the host-side command line tool
-#
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- $(amend_src_files) \
- $(amend_test_files) \
- register.c \
- main.c
-
-LOCAL_CFLAGS := $(amend_cflags) -g -O0
-LOCAL_MODULE := amend
-LOCAL_YACCFLAGS := -v
-
-include $(BUILD_HOST_EXECUTABLE)
-
-#
-# Build the device-side library
-#
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(amend_src_files)
-LOCAL_SRC_FILES += $(amend_test_files)
-
-LOCAL_CFLAGS := $(amend_cflags)
-LOCAL_MODULE := libamend
-
-include $(BUILD_STATIC_LIBRARY)
diff --git a/amend/amend.c b/amend/amend.c
deleted file mode 100644
index 6f706d0..0000000
--- a/amend/amend.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 <stdlib.h>
-#include "amend.h"
-#include "lexer.h"
-#include "parser.h"
-
-extern const AmCommandList *gCommands;
-
-const AmCommandList *
-parseAmendScript(const char *buf, size_t bufLen)
-{
- setLexerInputBuffer(buf, bufLen);
- int ret = yyparse();
- if (ret != 0) {
- return NULL;
- }
- return gCommands;
-}
diff --git a/amend/amend.h b/amend/amend.h
deleted file mode 100644
index 416f974..0000000
--- a/amend/amend.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 AMEND_H_
-#define AMEND_H_
-
-#include "ast.h"
-#include "execute.h"
-
-const AmCommandList *parseAmendScript(const char *buf, size_t bufLen);
-
-#endif // AMEND_H_
diff --git a/amend/ast.c b/amend/ast.c
deleted file mode 100644
index f53efdc..0000000
--- a/amend/ast.c
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 <stdio.h>
-#include "ast.h"
-
-static const char gSpaces[] =
- " "
- " "
- " "
- " "
- " "
- " "
- " ";
-const int gSpacesMax = sizeof(gSpaces) - 1;
-
-static const char *
-pad(int level)
-{
- level *= 4;
- if (level > gSpacesMax) {
- level = gSpacesMax;
- }
- return gSpaces + gSpacesMax - level;
-}
-
-void dumpBooleanValue(int level, const AmBooleanValue *booleanValue);
-void dumpStringValue(int level, const AmStringValue *stringValue);
-
-void
-dumpBooleanExpression(int level, const AmBooleanExpression *booleanExpression)
-{
- const char *op;
- bool unary = false;
-
- switch (booleanExpression->op) {
- case AM_BOP_NOT:
- op = "NOT";
- unary = true;
- break;
- case AM_BOP_EQ:
- op = "EQ";
- break;
- case AM_BOP_NE:
- op = "NE";
- break;
- case AM_BOP_AND:
- op = "AND";
- break;
- case AM_BOP_OR:
- op = "OR";
- break;
- default:
- op = "??";
- break;
- }
-
- printf("%sBOOLEAN %s {\n", pad(level), op);
- dumpBooleanValue(level + 1, booleanExpression->arg1);
- if (!unary) {
- dumpBooleanValue(level + 1, booleanExpression->arg2);
- }
- printf("%s}\n", pad(level));
-}
-
-void
-dumpFunctionArguments(int level, const AmFunctionArguments *functionArguments)
-{
- int i;
- for (i = 0; i < functionArguments->argc; i++) {
- dumpStringValue(level, &functionArguments->argv[i]);
- }
-}
-
-void
-dumpFunctionCall(int level, const AmFunctionCall *functionCall)
-{
- printf("%sFUNCTION %s (\n", pad(level), functionCall->name);
- dumpFunctionArguments(level + 1, functionCall->args);
- printf("%s)\n", pad(level));
-}
-
-void
-dumpStringValue(int level, const AmStringValue *stringValue)
-{
- switch (stringValue->type) {
- case AM_SVAL_LITERAL:
- printf("%s\"%s\"\n", pad(level), stringValue->u.literal);
- break;
- case AM_SVAL_FUNCTION:
- dumpFunctionCall(level, stringValue->u.function);
- break;
- default:
- printf("%s<UNKNOWN SVAL TYPE %d>\n", pad(level), stringValue->type);
- break;
- }
-}
-
-void
-dumpStringComparisonExpression(int level,
- const AmStringComparisonExpression *stringComparisonExpression)
-{
- const char *op;
-
- switch (stringComparisonExpression->op) {
- case AM_SOP_LT:
- op = "LT";
- break;
- case AM_SOP_LE:
- op = "LE";
- break;
- case AM_SOP_GT:
- op = "GT";
- break;
- case AM_SOP_GE:
- op = "GE";
- break;
- case AM_SOP_EQ:
- op = "EQ";
- break;
- case AM_SOP_NE:
- op = "NE";
- break;
- default:
- op = "??";
- break;
- }
- printf("%sSTRING %s {\n", pad(level), op);
- dumpStringValue(level + 1, stringComparisonExpression->arg1);
- dumpStringValue(level + 1, stringComparisonExpression->arg2);
- printf("%s}\n", pad(level));
-}
-
-void
-dumpBooleanValue(int level, const AmBooleanValue *booleanValue)
-{
- switch (booleanValue->type) {
- case AM_BVAL_EXPRESSION:
- dumpBooleanExpression(level, &booleanValue->u.expression);
- break;
- case AM_BVAL_STRING_COMPARISON:
- dumpStringComparisonExpression(level,
- &booleanValue->u.stringComparison);
- break;
- default:
- printf("%s<UNKNOWN BVAL TYPE %d>\n", pad(1), booleanValue->type);
- break;
- }
-}
-
-void
-dumpWordList(const AmWordList *wordList)
-{
- int i;
- for (i = 0; i < wordList->argc; i++) {
- printf("%s\"%s\"\n", pad(1), wordList->argv[i]);
- }
-}
-
-void
-dumpCommandArguments(const AmCommandArguments *commandArguments)
-{
- if (commandArguments->booleanArgs) {
- dumpBooleanValue(1, commandArguments->u.b);
- } else {
- dumpWordList(commandArguments->u.w);
- }
-}
-
-void
-dumpCommand(const AmCommand *command)
-{
- printf("command \"%s\" {\n", command->name);
- dumpCommandArguments(command->args);
- printf("}\n");
-}
-
-void
-dumpCommandList(const AmCommandList *commandList)
-{
- int i;
- for (i = 0; i < commandList->commandCount; i++) {
- dumpCommand(commandList->commands[i]);
- }
-}
diff --git a/amend/ast.h b/amend/ast.h
deleted file mode 100644
index 7834a2b..0000000
--- a/amend/ast.h
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 AMEND_AST_H_
-#define AMEND_AST_H_
-
-#include "commands.h"
-
-typedef struct AmStringValue AmStringValue;
-
-typedef struct {
- int argc;
- AmStringValue *argv;
-} AmFunctionArguments;
-
-/* An internal structure used only by the parser;
- * will not appear in the output AST.
-xxx try to move this into parser.h
- */
-typedef struct AmFunctionArgumentBuilder AmFunctionArgumentBuilder;
-struct AmFunctionArgumentBuilder {
- AmFunctionArgumentBuilder *next;
- AmStringValue *arg;
- int argCount;
-};
-
-typedef struct AmWordListBuilder AmWordListBuilder;
-struct AmWordListBuilder {
- AmWordListBuilder *next;
- const char *word;
- int wordCount;
-};
-
-typedef struct {
- const char *name;
- Function *fn;
- AmFunctionArguments *args;
-} AmFunctionCall;
-
-
-/* <string-value> ::=
- * <literal-string> |
- * <function-call>
- */
-struct AmStringValue {
- unsigned int line;
-
- enum {
- AM_SVAL_LITERAL,
- AM_SVAL_FUNCTION,
- } type;
- union {
- const char *literal;
-//xxx inline instead of using pointers
- AmFunctionCall *function;
- } u;
-};
-
-
-/* <string-comparison-expression> ::=
- * <string-value> <string-comparison-operator> <string-value>
- */
-typedef struct {
- unsigned int line;
-
- enum {
- AM_SOP_LT,
- AM_SOP_LE,
- AM_SOP_GT,
- AM_SOP_GE,
- AM_SOP_EQ,
- AM_SOP_NE,
- } op;
- AmStringValue *arg1;
- AmStringValue *arg2;
-} AmStringComparisonExpression;
-
-
-/* <boolean-expression> ::=
- * ! <boolean-value> |
- * <boolean-value> <binary-boolean-operator> <boolean-value>
- */
-typedef struct AmBooleanValue AmBooleanValue;
-typedef struct {
- unsigned int line;
-
- enum {
- AM_BOP_NOT,
-
- AM_BOP_EQ,
- AM_BOP_NE,
-
- AM_BOP_AND,
-
- AM_BOP_OR,
- } op;
- AmBooleanValue *arg1;
- AmBooleanValue *arg2;
-} AmBooleanExpression;
-
-
-/* <boolean-value> ::=
- * <boolean-expression> |
- * <string-comparison-expression>
- */
-struct AmBooleanValue {
- unsigned int line;
-
- enum {
- AM_BVAL_EXPRESSION,
- AM_BVAL_STRING_COMPARISON,
- } type;
- union {
- AmBooleanExpression expression;
- AmStringComparisonExpression stringComparison;
- } u;
-};
-
-
-typedef struct {
- unsigned int line;
-
- int argc;
- const char **argv;
-} AmWordList;
-
-
-typedef struct {
- bool booleanArgs;
- union {
- AmWordList *w;
- AmBooleanValue *b;
- } u;
-} AmCommandArguments;
-
-typedef struct {
- unsigned int line;
-
- const char *name;
- Command *cmd;
- AmCommandArguments *args;
-} AmCommand;
-
-typedef struct {
- AmCommand **commands;
- int commandCount;
- int arraySize;
-} AmCommandList;
-
-void dumpCommandList(const AmCommandList *commandList);
-
-#endif // AMEND_AST_H_
diff --git a/amend/commands.c b/amend/commands.c
deleted file mode 100644
index 78121ad..0000000
--- a/amend/commands.c
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include "symtab.h"
-#include "commands.h"
-
-#if 1
-#define TRACE(...) printf(__VA_ARGS__)
-#else
-#define TRACE(...) /**/
-#endif
-
-typedef enum {
- CMD_TYPE_UNKNOWN = -1,
- CMD_TYPE_COMMAND = 0,
- CMD_TYPE_FUNCTION
-} CommandType;
-
-typedef struct {
- const char *name;
- void *cookie;
- CommandType type;
- CommandArgumentType argType;
- CommandHook hook;
-} CommandEntry;
-
-static struct {
- SymbolTable *symbolTable;
- bool commandStateInitialized;
-} gCommandState;
-
-int
-commandInit()
-{
- if (gCommandState.commandStateInitialized) {
- return -1;
- }
- gCommandState.symbolTable = createSymbolTable();
- if (gCommandState.symbolTable == NULL) {
- return -1;
- }
- gCommandState.commandStateInitialized = true;
- return 0;
-}
-
-void
-commandCleanup()
-{
- if (gCommandState.commandStateInitialized) {
- gCommandState.commandStateInitialized = false;
- deleteSymbolTable(gCommandState.symbolTable);
- gCommandState.symbolTable = NULL;
-//xxx need to free the entries and names in the symbol table
- }
-}
-
-static int
-registerCommandInternal(const char *name, CommandType type,
- CommandArgumentType argType, CommandHook hook, void *cookie)
-{
- CommandEntry *entry;
-
- if (!gCommandState.commandStateInitialized) {
- return -1;
- }
- if (name == NULL || hook == NULL) {
- return -1;
- }
- if (type != CMD_TYPE_COMMAND && type != CMD_TYPE_FUNCTION) {
- return -1;
- }
- if (argType != CMD_ARGS_BOOLEAN && argType != CMD_ARGS_WORDS) {
- return -1;
- }
-
- entry = (CommandEntry *)malloc(sizeof(CommandEntry));
- if (entry != NULL) {
- entry->name = strdup(name);
- if (entry->name != NULL) {
- int ret;
-
- entry->cookie = cookie;
- entry->type = type;
- entry->argType = argType;
- entry->hook = hook;
- ret = addToSymbolTable(gCommandState.symbolTable,
- entry->name, entry->type, entry);
- if (ret == 0) {
- return 0;
- }
- }
- free(entry);
- }
-
- return -1;
-}
-
-int
-registerCommand(const char *name,
- CommandArgumentType argType, CommandHook hook, void *cookie)
-{
- return registerCommandInternal(name,
- CMD_TYPE_COMMAND, argType, hook, cookie);
-}
-
-int
-registerFunction(const char *name, FunctionHook hook, void *cookie)
-{
- return registerCommandInternal(name,
- CMD_TYPE_FUNCTION, CMD_ARGS_WORDS, (CommandHook)hook, cookie);
-}
-
-Command *
-findCommand(const char *name)
-{
- return (Command *)findInSymbolTable(gCommandState.symbolTable,
- name, CMD_TYPE_COMMAND);
-}
-
-Function *
-findFunction(const char *name)
-{
- return (Function *)findInSymbolTable(gCommandState.symbolTable,
- name, CMD_TYPE_FUNCTION);
-}
-
-CommandArgumentType
-getCommandArgumentType(Command *cmd)
-{
- CommandEntry *entry = (CommandEntry *)cmd;
-
- if (entry != NULL) {
- return entry->argType;
- }
- return CMD_ARGS_UNKNOWN;
-}
-
-static int
-callCommandInternal(CommandEntry *entry, int argc, const char *argv[])
-{
- if (entry != NULL && entry->argType == CMD_ARGS_WORDS &&
- (argc == 0 || (argc > 0 && argv != NULL)))
- {
- int i;
- for (i = 0; i < argc; i++) {
- if (argv[i] == NULL) {
- goto bail;
- }
- }
- TRACE("calling command %s\n", entry->name);
- return entry->hook(entry->name, entry->cookie, argc, argv);
- }
-bail:
- return -1;
-}
-
-static int
-callBooleanCommandInternal(CommandEntry *entry, bool arg)
-{
- if (entry != NULL && entry->argType == CMD_ARGS_BOOLEAN) {
- TRACE("calling boolean command %s\n", entry->name);
- return entry->hook(entry->name, entry->cookie, arg ? 1 : 0, NULL);
- }
- return -1;
-}
-
-int
-callCommand(Command *cmd, int argc, const char *argv[])
-{
- return callCommandInternal((CommandEntry *)cmd, argc, argv);
-}
-
-int
-callBooleanCommand(Command *cmd, bool arg)
-{
- return callBooleanCommandInternal((CommandEntry *)cmd, arg);
-}
-
-int
-callFunctionInternal(CommandEntry *entry, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- if (entry != NULL && entry->argType == CMD_ARGS_WORDS &&
- (argc == 0 || (argc > 0 && argv != NULL)))
- {
- if (result != NULL)
- {
- /* This is the actual invocation of the function,
- * which means that none of the arguments are allowed
- * to be NULL.
- */
- int i;
- for (i = 0; i < argc; i++) {
- if (argv[i] == NULL) {
- goto bail;
- }
- }
- TRACE("calling function %s\n", entry->name);
- return ((FunctionHook)entry->hook)(entry->name, entry->cookie,
- argc, argv, result, resultLen);
- }
- }
-bail:
- return -1;
-}
-
-int
-callFunction(Function *fn, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- return callFunctionInternal((CommandEntry *)fn, argc, argv,
- result, resultLen);
-}
diff --git a/amend/commands.h b/amend/commands.h
deleted file mode 100644
index 6c97e55..0000000
--- a/amend/commands.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 <stdbool.h>
-
-#ifndef AMEND_COMMANDS_H_
-#define AMEND_COMMANDS_H_
-
-/* Invoke a command.
- *
- * When a boolean command is called, "argc" is the boolean value and
- * "argv" is NULL.
- */
-typedef int (*CommandHook)(const char *name, void *cookie,
- int argc, const char *argv[]);
-
-int commandInit(void);
-void commandCleanup(void);
-
-/*
- * Command management
- */
-
-struct Command;
-typedef struct Command Command;
-
-typedef enum {
- CMD_ARGS_UNKNOWN = -1,
- CMD_ARGS_BOOLEAN = 0,
- CMD_ARGS_WORDS
-} CommandArgumentType;
-
-int registerCommand(const char *name,
- CommandArgumentType argType, CommandHook hook, void *cookie);
-
-Command *findCommand(const char *name);
-
-CommandArgumentType getCommandArgumentType(Command *cmd);
-
-int callCommand(Command *cmd, int argc, const char *argv[]);
-int callBooleanCommand(Command *cmd, bool arg);
-
-/*
- * Function management
- */
-
-typedef int (*FunctionHook)(const char *name, void *cookie,
- int argc, const char *argv[],
- char **result, size_t *resultLen);
-
-struct Function;
-typedef struct Function Function;
-
-int registerFunction(const char *name, FunctionHook hook, void *cookie);
-
-Function *findFunction(const char *name);
-
-int callFunction(Function *fn, int argc, const char *argv[],
- char **result, size_t *resultLen);
-
-#endif // AMEND_COMMANDS_H_
diff --git a/amend/execute.c b/amend/execute.c
deleted file mode 100644
index 9162ad6..0000000
--- a/amend/execute.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#undef NDEBUG
-#include <assert.h>
-#include "ast.h"
-#include "execute.h"
-
-typedef struct {
- int c;
- const char **v;
-} StringList;
-
-static int execBooleanValue(ExecContext *ctx,
- const AmBooleanValue *booleanValue, bool *result);
-static int execStringValue(ExecContext *ctx, const AmStringValue *stringValue,
- const char **result);
-
-static int
-execBooleanExpression(ExecContext *ctx,
- const AmBooleanExpression *booleanExpression, bool *result)
-{
- int ret;
- bool arg1, arg2;
- bool unary;
-
- assert(ctx != NULL);
- assert(booleanExpression != NULL);
- assert(result != NULL);
- if (ctx == NULL || booleanExpression == NULL || result == NULL) {
- return -__LINE__;
- }
-
- if (booleanExpression->op == AM_BOP_NOT) {
- unary = true;
- } else {
- unary = false;
- }
-
- ret = execBooleanValue(ctx, booleanExpression->arg1, &arg1);
- if (ret != 0) return ret;
-
- if (!unary) {
- ret = execBooleanValue(ctx, booleanExpression->arg2, &arg2);
- if (ret != 0) return ret;
- } else {
- arg2 = false;
- }
-
- switch (booleanExpression->op) {
- case AM_BOP_NOT:
- *result = !arg1;
- break;
- case AM_BOP_EQ:
- *result = (arg1 == arg2);
- break;
- case AM_BOP_NE:
- *result = (arg1 != arg2);
- break;
- case AM_BOP_AND:
- *result = (arg1 && arg2);
- break;
- case AM_BOP_OR:
- *result = (arg1 || arg2);
- break;
- default:
- return -__LINE__;
- }
-
- return 0;
-}
-
-static int
-execFunctionArguments(ExecContext *ctx,
- const AmFunctionArguments *functionArguments, StringList *result)
-{
- int ret;
-
- assert(ctx != NULL);
- assert(functionArguments != NULL);
- assert(result != NULL);
- if (ctx == NULL || functionArguments == NULL || result == NULL) {
- return -__LINE__;
- }
-
- result->c = functionArguments->argc;
- result->v = (const char **)malloc(result->c * sizeof(const char *));
- if (result->v == NULL) {
- result->c = 0;
- return -__LINE__;
- }
-
- int i;
- for (i = 0; i < functionArguments->argc; i++) {
- ret = execStringValue(ctx, &functionArguments->argv[i], &result->v[i]);
- if (ret != 0) {
- result->c = 0;
- free(result->v);
- //TODO: free the individual args, if we're responsible for them.
- result->v = NULL;
- return ret;
- }
- }
-
- return 0;
-}
-
-static int
-execFunctionCall(ExecContext *ctx, const AmFunctionCall *functionCall,
- const char **result)
-{
- int ret;
-
- assert(ctx != NULL);
- assert(functionCall != NULL);
- assert(result != NULL);
- if (ctx == NULL || functionCall == NULL || result == NULL) {
- return -__LINE__;
- }
-
- StringList args;
- ret = execFunctionArguments(ctx, functionCall->args, &args);
- if (ret != 0) {
- return ret;
- }
-
- ret = callFunction(functionCall->fn, args.c, args.v, (char **)result, NULL);
- if (ret != 0) {
- return ret;
- }
-
- //TODO: clean up args
-
- return 0;
-}
-
-static int
-execStringValue(ExecContext *ctx, const AmStringValue *stringValue,
- const char **result)
-{
- int ret;
-
- assert(ctx != NULL);
- assert(stringValue != NULL);
- assert(result != NULL);
- if (ctx == NULL || stringValue == NULL || result == NULL) {
- return -__LINE__;
- }
-
- switch (stringValue->type) {
- case AM_SVAL_LITERAL:
- *result = strdup(stringValue->u.literal);
- break;
- case AM_SVAL_FUNCTION:
- ret = execFunctionCall(ctx, stringValue->u.function, result);
- if (ret != 0) {
- return ret;
- }
- break;
- default:
- return -__LINE__;
- }
-
- return 0;
-}
-
-static int
-execStringComparisonExpression(ExecContext *ctx,
- const AmStringComparisonExpression *stringComparisonExpression,
- bool *result)
-{
- int ret;
-
- assert(ctx != NULL);
- assert(stringComparisonExpression != NULL);
- assert(result != NULL);
- if (ctx == NULL || stringComparisonExpression == NULL || result == NULL) {
- return -__LINE__;
- }
-
- const char *arg1, *arg2;
- ret = execStringValue(ctx, stringComparisonExpression->arg1, &arg1);
- if (ret != 0) {
- return ret;
- }
- ret = execStringValue(ctx, stringComparisonExpression->arg2, &arg2);
- if (ret != 0) {
- return ret;
- }
-
- int cmp = strcmp(arg1, arg2);
-
- switch (stringComparisonExpression->op) {
- case AM_SOP_LT:
- *result = (cmp < 0);
- break;
- case AM_SOP_LE:
- *result = (cmp <= 0);
- break;
- case AM_SOP_GT:
- *result = (cmp > 0);
- break;
- case AM_SOP_GE:
- *result = (cmp >= 0);
- break;
- case AM_SOP_EQ:
- *result = (cmp == 0);
- break;
- case AM_SOP_NE:
- *result = (cmp != 0);
- break;
- default:
- return -__LINE__;
- break;
- }
-
- return 0;
-}
-
-static int
-execBooleanValue(ExecContext *ctx, const AmBooleanValue *booleanValue,
- bool *result)
-{
- int ret;
-
- assert(ctx != NULL);
- assert(booleanValue != NULL);
- assert(result != NULL);
- if (ctx == NULL || booleanValue == NULL || result == NULL) {
- return -__LINE__;
- }
-
- switch (booleanValue->type) {
- case AM_BVAL_EXPRESSION:
- ret = execBooleanExpression(ctx, &booleanValue->u.expression, result);
- break;
- case AM_BVAL_STRING_COMPARISON:
- ret = execStringComparisonExpression(ctx,
- &booleanValue->u.stringComparison, result);
- break;
- default:
- ret = -__LINE__;
- break;
- }
-
- return ret;
-}
-
-static int
-execCommand(ExecContext *ctx, const AmCommand *command)
-{
- int ret;
-
- assert(ctx != NULL);
- assert(command != NULL);
- if (ctx == NULL || command == NULL) {
- return -__LINE__;
- }
-
- CommandArgumentType argType;
- argType = getCommandArgumentType(command->cmd);
- switch (argType) {
- case CMD_ARGS_BOOLEAN:
- {
- bool bVal;
- ret = execBooleanValue(ctx, command->args->u.b, &bVal);
- if (ret == 0) {
- ret = callBooleanCommand(command->cmd, bVal);
- }
- }
- break;
- case CMD_ARGS_WORDS:
- {
- AmWordList *words = command->args->u.w;
- ret = callCommand(command->cmd, words->argc, words->argv);
- }
- break;
- default:
- ret = -__LINE__;
- break;
- }
-
- return ret;
-}
-
-int
-execCommandList(ExecContext *ctx, const AmCommandList *commandList)
-{
- int i;
- for (i = 0; i < commandList->commandCount; i++) {
- int ret = execCommand(ctx, commandList->commands[i]);
- if (ret != 0) {
- int line = commandList->commands[i]->line;
- return line > 0 ? line : ret;
- }
- }
-
- return 0;
-}
diff --git a/amend/execute.h b/amend/execute.h
deleted file mode 100644
index 3becb48..0000000
--- a/amend/execute.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 AMEND_EXECUTE_H_
-#define AMEND_EXECUTE_H_
-
-typedef struct ExecContext ExecContext;
-
-/* Returns 0 on success, otherwise the line number that failed. */
-int execCommandList(ExecContext *ctx, const AmCommandList *commandList);
-
-#endif // AMEND_EXECUTE_H_
diff --git a/amend/lexer.h b/amend/lexer.h
deleted file mode 100644
index fc716fd..0000000
--- a/amend/lexer.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 AMEND_LEXER_H_
-#define AMEND_LEXER_H_
-
-#define AMEND_LEXER_BUFFER_INPUT 1
-
-void yyerror(const char *msg);
-int yylex(void);
-
-#if AMEND_LEXER_BUFFER_INPUT
-void setLexerInputBuffer(const char *buf, size_t buflen);
-#else
-#include <stdio.h>
-void yyset_in(FILE *in_str);
-#endif
-
-const char *tokenToString(int token);
-
-typedef enum {
- AM_UNKNOWN_ARGS,
- AM_WORD_ARGS,
- AM_BOOLEAN_ARGS,
-} AmArgumentType;
-
-void setLexerArgumentType(AmArgumentType type);
-int getLexerLineNumber(void);
-
-#endif // AMEND_LEXER_H_
diff --git a/amend/lexer.l b/amend/lexer.l
deleted file mode 100644
index 80896d1..0000000
--- a/amend/lexer.l
+++ /dev/null
@@ -1,299 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 <stdio.h>
- #include <stdlib.h>
- #include "ast.h"
- #include "lexer.h"
- #include "parser.h"
-
- const char *tokenToString(int token)
- {
- static char scratch[128];
-
- switch (token) {
- case TOK_AND:
- return "&&";
- case TOK_OR:
- return "||";
- case TOK_EQ:
- return "==";
- case TOK_NE:
- return "!=";
- case TOK_GE:
- return ">=";
- case TOK_LE:
- return "<=";
- case TOK_EOF:
- return "EOF";
- case TOK_EOL:
- return "EOL\n";
- case TOK_STRING:
- snprintf(scratch, sizeof(scratch),
- "STRING<%s>", yylval.literalString);
- return scratch;
- case TOK_IDENTIFIER:
- snprintf(scratch, sizeof(scratch), "IDENTIFIER<%s>",
- yylval.literalString);
- return scratch;
- case TOK_WORD:
- snprintf(scratch, sizeof(scratch), "WORD<%s>",
- yylval.literalString);
- return scratch;
- default:
- if (token > ' ' && token <= '~') {
- scratch[0] = (char)token;
- scratch[1] = '\0';
- } else {
- snprintf(scratch, sizeof(scratch), "??? <%d>", token);
- }
- return scratch;
- }
- }
-
- typedef struct {
- char *value;
- char *nextc;
- unsigned int alloc_size;
- } AmString;
-
- static int addCharToString(AmString *str, char c)
- {
- if ((unsigned int)(str->nextc - str->value) >= str->alloc_size) {
- char *new_value;
- unsigned int new_size;
-
- new_size = (str->alloc_size + 1) * 2;
- if (new_size < 64) {
- new_size = 64;
- }
-
- new_value = (char *)realloc(str->value, new_size);
- if (new_value == NULL) {
- yyerror("out of memory");
- return -1;
- }
- str->nextc = str->nextc - str->value + new_value;
- str->value = new_value;
- str->alloc_size = new_size;
- }
- *str->nextc++ = c;
- return 0;
- }
-
- static int setString(AmString *str, const char *p)
- {
- str->nextc = str->value;
- while (*p != '\0') {
-//TODO: add the whole string at once
- addCharToString(str, *p++);
- }
- return addCharToString(str, '\0');
- }
-
- static AmString gStr = { NULL, NULL, 0 };
- static int gLineNumber = 1;
- static AmArgumentType gArgumentType = AM_UNKNOWN_ARGS;
- static const char *gErrorMessage = NULL;
-
-#if AMEND_LEXER_BUFFER_INPUT
- static const char *gInputBuffer;
- static const char *gInputBufferNext;
- static const char *gInputBufferEnd;
-
-# define YY_INPUT(buf, result, max_size) \
- do { \
- int nbytes = gInputBufferEnd - gInputBufferNext; \
- if (nbytes > 0) { \
- if (nbytes > max_size) { \
- nbytes = max_size; \
- } \
- memcpy(buf, gInputBufferNext, nbytes); \
- gInputBufferNext += nbytes; \
- result = nbytes; \
- } else { \
- result = YY_NULL; \
- } \
- } while (false)
-#endif // AMEND_LEXER_BUFFER_INPUT
-
-%}
-
-%option noyywrap
-
-%x QUOTED_STRING BOOLEAN WORDS
-
-ident [a-zA-Z_][a-zA-Z_0-9]*
-word [^ \t\r\n"]+
-
-%%
- /* This happens at the beginning of each call to yylex().
- */
- if (gArgumentType == AM_WORD_ARGS) {
- BEGIN(WORDS);
- } else if (gArgumentType == AM_BOOLEAN_ARGS) {
- BEGIN(BOOLEAN);
- }
-
- /*xxx require everything to be 7-bit-clean, printable characters */
-<INITIAL>{
- {ident}/[ \t\r\n] {
- /* The only token we recognize in the initial
- * state is an identifier followed by whitespace.
- */
- setString(&gStr, yytext);
- yylval.literalString = gStr.value;
- return TOK_IDENTIFIER;
- }
- }
-
-<BOOLEAN>{
- {ident} {
- /* Non-quoted identifier-style string */
- setString(&gStr, yytext);
- yylval.literalString = gStr.value;
- return TOK_IDENTIFIER;
- }
- "&&" return TOK_AND;
- "||" return TOK_OR;
- "==" return TOK_EQ;
- "!=" return TOK_NE;
- ">=" return TOK_GE;
- "<=" return TOK_LE;
- [<>()!,] return yytext[0];
- }
-
- /* Double-quoted string handling */
-
-<WORDS,BOOLEAN>\" {
- /* Initial quote */
- gStr.nextc = gStr.value;
- BEGIN(QUOTED_STRING);
- }
-
-<QUOTED_STRING>{
- \" {
- /* Closing quote */
- BEGIN(INITIAL);
- addCharToString(&gStr, '\0');
- yylval.literalString = gStr.value;
- if (gArgumentType == AM_WORD_ARGS) {
- return TOK_WORD;
- } else {
- return TOK_STRING;
- }
- }
-
- <<EOF>> |
- \n {
- /* Unterminated string */
- yyerror("unterminated string");
- return TOK_ERROR;
- }
-
- \\\" {
- /* Escaped quote */
- addCharToString(&gStr, '"');
- }
-
- \\\\ {
- /* Escaped backslash */
- addCharToString(&gStr, '\\');
- }
-
- \\. {
- /* No other escapes allowed. */
- gErrorMessage = "illegal escape";
- return TOK_ERROR;
- }
-
- [^\\\n\"]+ {
- /* String contents */
- char *p = yytext;
- while (*p != '\0') {
- /* TODO: add the whole string at once */
- addCharToString(&gStr, *p++);
- }
- }
- }
-
-<WORDS>{
- /*xxx look out for backslashes; escape backslashes and quotes */
- /*xxx if a quote is right against a char, we should append */
- {word} {
- /* Whitespace-separated word */
- setString(&gStr, yytext);
- yylval.literalString = gStr.value;
- return TOK_WORD;
- }
- }
-
-<INITIAL,WORDS,BOOLEAN>{
- \n {
- /* Count lines */
- gLineNumber++;
- gArgumentType = AM_UNKNOWN_ARGS;
- BEGIN(INITIAL);
- return TOK_EOL;
- }
-
- /*xxx backslashes to extend lines? */
- /* Skip whitespace and comments.
- */
- [ \t\r]+ ;
- #.* ;
-
- . {
- /* Fail on anything we didn't expect. */
- gErrorMessage = "unexpected character";
- return TOK_ERROR;
- }
- }
-%%
-
-void
-yyerror(const char *msg)
-{
- if (!strcmp(msg, "syntax error") && gErrorMessage != NULL) {
- msg = gErrorMessage;
- gErrorMessage = NULL;
- }
- fprintf(stderr, "line %d: %s at '%s'\n", gLineNumber, msg, yytext);
-}
-
-#if AMEND_LEXER_BUFFER_INPUT
-void
-setLexerInputBuffer(const char *buf, size_t buflen)
-{
- gLineNumber = 1;
- gInputBuffer = buf;
- gInputBufferNext = gInputBuffer;
- gInputBufferEnd = gInputBuffer + buflen;
-}
-#endif // AMEND_LEXER_BUFFER_INPUT
-
-void
-setLexerArgumentType(AmArgumentType type)
-{
- gArgumentType = type;
-}
-
-int
-getLexerLineNumber(void)
-{
- return gLineNumber;
-}
diff --git a/amend/main.c b/amend/main.c
deleted file mode 100644
index bc9e587..0000000
--- a/amend/main.c
+++ /dev/null
@@ -1,189 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "ast.h"
-#include "lexer.h"
-#include "parser.h"
-#include "register.h"
-#include "execute.h"
-
-void
-lexTest()
-{
- int token;
- do {
- token = yylex();
- if (token == 0) {
- printf(" EOF");
- fflush(stdout);
- break;
- } else {
- printf(" %s", tokenToString(token));
- fflush(stdout);
- if (token == TOK_IDENTIFIER) {
- if (strcmp(yylval.literalString, "assert") == 0) {
- setLexerArgumentType(AM_BOOLEAN_ARGS);
- } else {
- setLexerArgumentType(AM_WORD_ARGS);
- }
- do {
- token = yylex();
- printf(" %s", tokenToString(token));
- fflush(stdout);
- } while (token != TOK_EOL && token != TOK_EOF && token != 0);
- } else if (token != TOK_EOL) {
- fprintf(stderr, "syntax error: expected identifier\n");
- break;
- }
- }
- } while (token != 0);
- printf("\n");
-}
-
-void
-usage()
-{
- printf("usage: amend [--debug-lex|--debug-ast] [<filename>]\n");
- exit(1);
-}
-
-extern const AmCommandList *gCommands;
-int
-main(int argc, char *argv[])
-{
- FILE *inputFile = NULL;
- bool debugLex = false;
- bool debugAst = false;
- const char *fileName = NULL;
- int err;
-
-#if 1
- extern int test_symtab(void);
- int ret = test_symtab();
- if (ret != 0) {
- fprintf(stderr, "test_symtab() failed: %d\n", ret);
- exit(ret);
- }
- extern int test_cmd_fn(void);
- ret = test_cmd_fn();
- if (ret != 0) {
- fprintf(stderr, "test_cmd_fn() failed: %d\n", ret);
- exit(ret);
- }
-#endif
-
- argc--;
- argv++;
- while (argc > 0) {
- if (strcmp("--debug-lex", argv[0]) == 0) {
- debugLex = true;
- } else if (strcmp("--debug-ast", argv[0]) == 0) {
- debugAst = true;
- } else if (argv[0][0] == '-') {
- fprintf(stderr, "amend: Unknown option \"%s\"\n", argv[0]);
- usage();
- } else {
- fileName = argv[0];
- }
- argc--;
- argv++;
- }
-
- if (fileName != NULL) {
- inputFile = fopen(fileName, "r");
- if (inputFile == NULL) {
- fprintf(stderr, "amend: Can't open input file '%s'\n", fileName);
- usage();
- }
- }
-
- commandInit();
-//xxx clean up
-
- err = registerUpdateCommands();
- if (err < 0) {
- fprintf(stderr, "amend: Error registering commands: %d\n", err);
- exit(-err);
- }
- err = registerUpdateFunctions();
- if (err < 0) {
- fprintf(stderr, "amend: Error registering functions: %d\n", err);
- exit(-err);
- }
-
-#if AMEND_LEXER_BUFFER_INPUT
- if (inputFile == NULL) {
- fprintf(stderr, "amend: No input file\n");
- usage();
- }
- char *fileData;
- int fileDataLen;
- fseek(inputFile, 0, SEEK_END);
- fileDataLen = ftell(inputFile);
- rewind(inputFile);
- if (fileDataLen < 0) {
- fprintf(stderr, "amend: Can't get file length\n");
- exit(2);
- } else if (fileDataLen == 0) {
- printf("amend: Empty input file\n");
- exit(0);
- }
- fileData = (char *)malloc(fileDataLen + 1);
- if (fileData == NULL) {
- fprintf(stderr, "amend: Can't allocate %d bytes\n", fileDataLen + 1);
- exit(2);
- }
- size_t nread = fread(fileData, 1, fileDataLen, inputFile);
- if (nread != (size_t)fileDataLen) {
- fprintf(stderr, "amend: Didn't read %d bytes, only %zd\n", fileDataLen,
- nread);
- exit(2);
- }
- fileData[fileDataLen] = '\0';
- setLexerInputBuffer(fileData, fileDataLen);
-#else
- if (inputFile == NULL) {
- inputFile = stdin;
- }
- yyset_in(inputFile);
-#endif
-
- if (debugLex) {
- lexTest();
- } else {
- int ret = yyparse();
- if (ret != 0) {
- fprintf(stderr, "amend: Parse failed (%d)\n", ret);
- exit(2);
- } else {
- if (debugAst) {
- dumpCommandList(gCommands);
- }
-printf("amend: Parse successful.\n");
- ret = execCommandList((ExecContext *)1, gCommands);
- if (ret != 0) {
- fprintf(stderr, "amend: Execution failed (%d)\n", ret);
- exit(3);
- }
-printf("amend: Execution successful.\n");
- }
- }
-
- return 0;
-}
diff --git a/amend/parser.h b/amend/parser.h
deleted file mode 100644
index aeb8657..0000000
--- a/amend/parser.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 AMEND_PARSER_H_
-#define AMEND_PARSER_H_
-
-#include "parser_y.h"
-
-int yyparse(void);
-
-#endif // AMEND_PARSER_H_
diff --git a/amend/parser_y.y b/amend/parser_y.y
deleted file mode 100644
index b634016..0000000
--- a/amend/parser_y.y
+++ /dev/null
@@ -1,430 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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.
- */
-
-%{
-#undef NDEBUG
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- #include <stdio.h>
- #include "ast.h"
- #include "lexer.h"
- #include "commands.h"
-
- void yyerror(const char *msg);
- int yylex(void);
-
-#define STRING_COMPARISON(out, a1, sop, a2) \
- do { \
- out = (AmBooleanValue *)malloc(sizeof(AmBooleanValue)); \
- if (out == NULL) { \
- YYABORT; \
- } \
- out->type = AM_BVAL_STRING_COMPARISON; \
- out->u.stringComparison.op = sop; \
- out->u.stringComparison.arg1 = a1; \
- out->u.stringComparison.arg2 = a2; \
- } while (false)
-
-#define BOOLEAN_EXPRESSION(out, a1, bop, a2) \
- do { \
- out = (AmBooleanValue *)malloc(sizeof(AmBooleanValue)); \
- if (out == NULL) { \
- YYABORT; \
- } \
- out->type = AM_BVAL_EXPRESSION; \
- out->u.expression.op = bop; \
- out->u.expression.arg1 = a1; \
- out->u.expression.arg2 = a2; \
- } while (false)
-
-AmCommandList *gCommands = NULL;
-%}
-
-%start lines
-
-%union {
- char *literalString;
- AmFunctionArgumentBuilder *functionArgumentBuilder;
- AmFunctionArguments *functionArguments;
- AmFunctionCall *functionCall;
- AmStringValue *stringValue;
- AmBooleanValue *booleanValue;
- AmWordListBuilder *wordListBuilder;
- AmCommandArguments *commandArguments;
- AmCommand *command;
- AmCommandList *commandList;
- }
-
-%token TOK_AND TOK_OR TOK_EQ TOK_NE TOK_GE TOK_LE TOK_EOF TOK_EOL TOK_ERROR
-%token <literalString> TOK_STRING TOK_IDENTIFIER TOK_WORD
-
-%type <commandList> lines
-%type <command> command line
-%type <functionArgumentBuilder> function_arguments
-%type <functionArguments> function_arguments_or_empty
-%type <functionCall> function_call
-%type <literalString> function_name
-%type <stringValue> string_value
-%type <booleanValue> boolean_expression
-%type <wordListBuilder> word_list
-%type <commandArguments> arguments
-
-/* Operator precedence, weakest to strongest.
- * Same as C/Java precedence.
- */
-
-%left TOK_OR
-%left TOK_AND
-%left TOK_EQ TOK_NE
-%left '<' '>' TOK_LE TOK_GE
-%right '!'
-
-%%
-
-lines : /* empty */
- {
- $$ = (AmCommandList *)malloc(sizeof(AmCommandList));
- if ($$ == NULL) {
- YYABORT;
- }
-gCommands = $$;
- $$->arraySize = 64;
- $$->commandCount = 0;
- $$->commands = (AmCommand **)malloc(
- sizeof(AmCommand *) * $$->arraySize);
- if ($$->commands == NULL) {
- YYABORT;
- }
- }
- | lines line
- {
- if ($2 != NULL) {
- if ($1->commandCount >= $1->arraySize) {
- AmCommand **newArray;
- newArray = (AmCommand **)realloc($$->commands,
- sizeof(AmCommand *) * $$->arraySize * 2);
- if (newArray == NULL) {
- YYABORT;
- }
- $$->commands = newArray;
- $$->arraySize *= 2;
- }
- $1->commands[$1->commandCount++] = $2;
- }
- }
- ;
-
-line : line_ending
- {
- $$ = NULL; /* ignore blank lines */
- }
- | command arguments line_ending
- {
- $$ = $1;
- $$->args = $2;
- setLexerArgumentType(AM_UNKNOWN_ARGS);
- }
- ;
-
-command : TOK_IDENTIFIER
- {
- Command *cmd = findCommand($1);
- if (cmd == NULL) {
- fprintf(stderr, "Unknown command \"%s\"\n", $1);
- YYABORT;
- }
- $$ = (AmCommand *)malloc(sizeof(AmCommand));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->line = getLexerLineNumber();
- $$->name = strdup($1);
- if ($$->name == NULL) {
- YYABORT;
- }
- $$->args = NULL;
- CommandArgumentType argType = getCommandArgumentType(cmd);
- if (argType == CMD_ARGS_BOOLEAN) {
- setLexerArgumentType(AM_BOOLEAN_ARGS);
- } else {
- setLexerArgumentType(AM_WORD_ARGS);
- }
- $$->cmd = cmd;
- }
- ;
-
-line_ending :
- TOK_EOL
- | TOK_EOF
- ;
-
-arguments : boolean_expression
- {
- $$ = (AmCommandArguments *)malloc(
- sizeof(AmCommandArguments));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->booleanArgs = true;
- $$->u.b = $1;
- }
- | word_list
- {
- /* Convert the builder list into an array.
- * Do it in reverse order; the words were pushed
- * onto the list in LIFO order.
- */
- AmWordList *w = (AmWordList *)malloc(sizeof(AmWordList));
- if (w == NULL) {
- YYABORT;
- }
- if ($1 != NULL) {
- AmWordListBuilder *words = $1;
-
- w->argc = words->wordCount;
- w->argv = (const char **)malloc(w->argc *
- sizeof(char *));
- if (w->argv == NULL) {
- YYABORT;
- }
- int i;
- for (i = w->argc; words != NULL && i > 0; --i) {
- AmWordListBuilder *f = words;
- w->argv[i-1] = words->word;
- words = words->next;
- free(f);
- }
- assert(i == 0);
- assert(words == NULL);
- } else {
- w->argc = 0;
- w->argv = NULL;
- }
- $$ = (AmCommandArguments *)malloc(
- sizeof(AmCommandArguments));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->booleanArgs = false;
- $$->u.w = w;
- }
- ;
-
-word_list : /* empty */
- { $$ = NULL; }
- | word_list TOK_WORD
- {
- if ($1 == NULL) {
- $$ = (AmWordListBuilder *)malloc(
- sizeof(AmWordListBuilder));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->next = NULL;
- $$->wordCount = 1;
- } else {
- $$ = (AmWordListBuilder *)malloc(
- sizeof(AmWordListBuilder));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->next = $1;
- $$->wordCount = $$->next->wordCount + 1;
- }
- $$->word = strdup($2);
- if ($$->word == NULL) {
- YYABORT;
- }
- }
- ;
-
-boolean_expression :
- '!' boolean_expression
- {
- $$ = (AmBooleanValue *)malloc(sizeof(AmBooleanValue));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->type = AM_BVAL_EXPRESSION;
- $$->u.expression.op = AM_BOP_NOT;
- $$->u.expression.arg1 = $2;
- $$->u.expression.arg2 = NULL;
- }
- /* TODO: if both expressions are literals, evaluate now */
- | boolean_expression TOK_AND boolean_expression
- { BOOLEAN_EXPRESSION($$, $1, AM_BOP_AND, $3); }
- | boolean_expression TOK_OR boolean_expression
- { BOOLEAN_EXPRESSION($$, $1, AM_BOP_OR, $3); }
- | boolean_expression TOK_EQ boolean_expression
- { BOOLEAN_EXPRESSION($$, $1, AM_BOP_EQ, $3); }
- | boolean_expression TOK_NE boolean_expression
- { BOOLEAN_EXPRESSION($$, $1, AM_BOP_NE, $3); }
- | '(' boolean_expression ')'
- { $$ = $2; }
- /* TODO: if both strings are literals, evaluate now */
- | string_value '<' string_value
- { STRING_COMPARISON($$, $1, AM_SOP_LT, $3); }
- | string_value '>' string_value
- { STRING_COMPARISON($$, $1, AM_SOP_GT, $3); }
- | string_value TOK_EQ string_value
- { STRING_COMPARISON($$, $1, AM_SOP_EQ, $3); }
- | string_value TOK_NE string_value
- { STRING_COMPARISON($$, $1, AM_SOP_NE, $3); }
- | string_value TOK_LE string_value
- { STRING_COMPARISON($$, $1, AM_SOP_LE, $3); }
- | string_value TOK_GE string_value
- { STRING_COMPARISON($$, $1, AM_SOP_GE, $3); }
- ;
-
-string_value :
- TOK_IDENTIFIER
- {
- $$ = (AmStringValue *)malloc(sizeof(AmStringValue));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->type = AM_SVAL_LITERAL;
- $$->u.literal = strdup($1);
- if ($$->u.literal == NULL) {
- YYABORT;
- }
- }
- | TOK_STRING
- {
- $$ = (AmStringValue *)malloc(sizeof(AmStringValue));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->type = AM_SVAL_LITERAL;
- $$->u.literal = strdup($1);
- if ($$->u.literal == NULL) {
- YYABORT;
- }
- }
- | function_call
- {
- $$ = (AmStringValue *)malloc(sizeof(AmStringValue));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->type = AM_SVAL_FUNCTION;
- $$->u.function = $1;
- }
- ;
-
- /* We can't just say
- * TOK_IDENTIFIER '(' function_arguments_or_empty ')'
- * because parsing function_arguments_or_empty will clobber
- * the underlying string that yylval.literalString points to.
- */
-function_call :
- function_name '(' function_arguments_or_empty ')'
- {
- Function *fn = findFunction($1);
- if (fn == NULL) {
- fprintf(stderr, "Unknown function \"%s\"\n", $1);
- YYABORT;
- }
- $$ = (AmFunctionCall *)malloc(sizeof(AmFunctionCall));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->name = $1;
- if ($$->name == NULL) {
- YYABORT;
- }
- $$->fn = fn;
- $$->args = $3;
- }
- ;
-
-function_name :
- TOK_IDENTIFIER
- {
- $$ = strdup($1);
- }
- ;
-
-function_arguments_or_empty :
- /* empty */
- {
- $$ = (AmFunctionArguments *)malloc(
- sizeof(AmFunctionArguments));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->argc = 0;
- $$->argv = NULL;
- }
- | function_arguments
- {
- AmFunctionArgumentBuilder *args = $1;
- assert(args != NULL);
-
- /* Convert the builder list into an array.
- * Do it in reverse order; the args were pushed
- * onto the list in LIFO order.
- */
- $$ = (AmFunctionArguments *)malloc(
- sizeof(AmFunctionArguments));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->argc = args->argCount;
- $$->argv = (AmStringValue *)malloc(
- $$->argc * sizeof(AmStringValue));
- if ($$->argv == NULL) {
- YYABORT;
- }
- int i;
- for (i = $$->argc; args != NULL && i > 0; --i) {
- AmFunctionArgumentBuilder *f = args;
- $$->argv[i-1] = *args->arg;
- args = args->next;
- free(f->arg);
- free(f);
- }
- assert(i == 0);
- assert(args == NULL);
- }
- ;
-
-function_arguments :
- string_value
- {
- $$ = (AmFunctionArgumentBuilder *)malloc(
- sizeof(AmFunctionArgumentBuilder));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->next = NULL;
- $$->argCount = 1;
- $$->arg = $1;
- }
- | function_arguments ',' string_value
- {
- $$ = (AmFunctionArgumentBuilder *)malloc(
- sizeof(AmFunctionArgumentBuilder));
- if ($$ == NULL) {
- YYABORT;
- }
- $$->next = $1;
- $$->argCount = $$->next->argCount + 1;
- $$->arg = $3;
- }
- ;
- /* xxx this whole tool needs to be hardened */
diff --git a/amend/register.c b/amend/register.c
deleted file mode 100644
index 0f44b74..0000000
--- a/amend/register.c
+++ /dev/null
@@ -1,338 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#undef NDEBUG
-#include <assert.h>
-#include "commands.h"
-
-#include "register.h"
-
-#define UNUSED(p) ((void)(p))
-
-#define CHECK_BOOL() \
- do { \
- assert(argv == NULL); \
- if (argv != NULL) return -1; \
- assert(argc == true || argc == false); \
- if (argc != true && argc != false) return -1; \
- } while (false)
-
-#define CHECK_WORDS() \
- do { \
- assert(argc >= 0); \
- if (argc < 0) return -1; \
- assert(argc == 0 || argv != NULL); \
- if (argc != 0 && argv == NULL) return -1; \
- } while (false)
-
-#define CHECK_FN() \
- do { \
- CHECK_WORDS(); \
- assert(result != NULL); \
- if (result == NULL) return -1; \
- } while (false)
-
-
-/*
- * Command definitions
- */
-
-/* assert <boolexpr>
- */
-static int
-cmd_assert(const char *name, void *cookie, int argc, const char *argv[])
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_BOOL();
-
- /* If our argument is false, return non-zero (failure)
- * If our argument is true, return zero (success)
- */
- if (argc) {
- return 0;
- } else {
- return 1;
- }
-}
-
-/* format <root>
- */
-static int
-cmd_format(const char *name, void *cookie, int argc, const char *argv[])
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_WORDS();
-//xxx
- return -1;
-}
-
-/* copy_dir <srcdir> <dstdir>
- */
-static int
-cmd_copy_dir(const char *name, void *cookie, int argc, const char *argv[])
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_WORDS();
-//xxx
- return -1;
-}
-
-/* mark <resource> dirty|clean
- */
-static int
-cmd_mark(const char *name, void *cookie, int argc, const char *argv[])
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_WORDS();
-//xxx when marking, save the top-level hash at the mark point
-// so we can retry on failure. Otherwise the hashes won't match,
-// or someone could intentionally dirty the FS to force a downgrade
-//xxx
- return -1;
-}
-
-/* done
- */
-static int
-cmd_done(const char *name, void *cookie, int argc, const char *argv[])
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_WORDS();
-//xxx
- return -1;
-}
-
-int
-registerUpdateCommands()
-{
- int ret;
-
- ret = registerCommand("assert", CMD_ARGS_BOOLEAN, cmd_assert, NULL);
- if (ret < 0) return ret;
-
- ret = registerCommand("copy_dir", CMD_ARGS_WORDS, cmd_copy_dir, NULL);
- if (ret < 0) return ret;
-
- ret = registerCommand("format", CMD_ARGS_WORDS, cmd_format, NULL);
- if (ret < 0) return ret;
-
- ret = registerCommand("mark", CMD_ARGS_WORDS, cmd_mark, NULL);
- if (ret < 0) return ret;
-
- ret = registerCommand("done", CMD_ARGS_WORDS, cmd_done, NULL);
- if (ret < 0) return ret;
-
- return 0;
-}
-
-
-/*
- * Function definitions
- */
-
-/* update_forced()
- *
- * Returns "true" if some system setting has determined that
- * the update should happen no matter what.
- */
-static int
-fn_update_forced(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_FN();
-
- if (argc != 0) {
- fprintf(stderr, "%s: wrong number of arguments (%d)\n",
- name, argc);
- return 1;
- }
-
- //xxx check some global or property
- bool force = true;
- if (force) {
- *result = strdup("true");
- } else {
- *result = strdup("");
- }
- if (resultLen != NULL) {
- *resultLen = strlen(*result);
- }
-
- return 0;
-}
-
-/* get_mark(<resource>)
- *
- * Returns the current mark associated with the provided resource.
- */
-static int
-fn_get_mark(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_FN();
-
- if (argc != 1) {
- fprintf(stderr, "%s: wrong number of arguments (%d)\n",
- name, argc);
- return 1;
- }
-
- //xxx look up the value
- *result = strdup("");
- if (resultLen != NULL) {
- *resultLen = strlen(*result);
- }
-
- return 0;
-}
-
-/* hash_dir(<path-to-directory>)
- */
-static int
-fn_hash_dir(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- int ret = -1;
-
- UNUSED(name);
- UNUSED(cookie);
- CHECK_FN();
-
- const char *dir;
- if (argc != 1) {
- fprintf(stderr, "%s: wrong number of arguments (%d)\n",
- name, argc);
- return 1;
- } else {
- dir = argv[0];
- }
-
-//xxx build and return the string
- *result = strdup("hashvalue");
- if (resultLen != NULL) {
- *resultLen = strlen(*result);
- }
- ret = 0;
-
- return ret;
-}
-
-/* matches(<str>, <str1> [, <strN>...])
- * If <str> matches (strcmp) any of <str1>...<strN>, returns <str>,
- * otherwise returns "".
- *
- * E.g., assert matches(hash_dir("/path"), "hash1", "hash2")
- */
-static int
-fn_matches(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_FN();
-
- if (argc < 2) {
- fprintf(stderr, "%s: not enough arguments (%d < 2)\n",
- name, argc);
- return 1;
- }
-
- int i;
- for (i = 1; i < argc; i++) {
- if (strcmp(argv[0], argv[i]) == 0) {
- *result = strdup(argv[0]);
- if (resultLen != NULL) {
- *resultLen = strlen(*result);
- }
- return 0;
- }
- }
-
- *result = strdup("");
- if (resultLen != NULL) {
- *resultLen = 1;
- }
- return 0;
-}
-
-/* concat(<str>, <str1> [, <strN>...])
- * Returns the concatenation of all strings.
- */
-static int
-fn_concat(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_FN();
-
- size_t totalLen = 0;
- int i;
- for (i = 0; i < argc; i++) {
- totalLen += strlen(argv[i]);
- }
-
- char *s = (char *)malloc(totalLen + 1);
- if (s == NULL) {
- return -1;
- }
- s[totalLen] = '\0';
- for (i = 0; i < argc; i++) {
- //TODO: keep track of the end to avoid walking the string each time
- strcat(s, argv[i]);
- }
- *result = s;
- if (resultLen != NULL) {
- *resultLen = strlen(s);
- }
-
- return 0;
-}
-
-int
-registerUpdateFunctions()
-{
- int ret;
-
- ret = registerFunction("update_forced", fn_update_forced, NULL);
- if (ret < 0) return ret;
-
- ret = registerFunction("get_mark", fn_get_mark, NULL);
- if (ret < 0) return ret;
-
- ret = registerFunction("hash_dir", fn_hash_dir, NULL);
- if (ret < 0) return ret;
-
- ret = registerFunction("matches", fn_matches, NULL);
- if (ret < 0) return ret;
-
- ret = registerFunction("concat", fn_concat, NULL);
- if (ret < 0) return ret;
-
- return 0;
-}
diff --git a/amend/register.h b/amend/register.h
deleted file mode 100644
index 1d9eacb..0000000
--- a/amend/register.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 AMEND_REGISTER_H_
-#define AMEND_REGISTER_H_
-
-int registerUpdateCommands(void);
-int registerUpdateFunctions(void);
-
-#endif // AMEND_REGISTER_H_
diff --git a/amend/symtab.c b/amend/symtab.c
deleted file mode 100644
index 835d2fc..0000000
--- a/amend/symtab.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 <stdlib.h>
-#include <string.h>
-#include "symtab.h"
-
-#define DEFAULT_TABLE_SIZE 16
-
-typedef struct {
- char *symbol;
- const void *cookie;
- unsigned int flags;
-} SymbolTableEntry;
-
-struct SymbolTable {
- SymbolTableEntry *table;
- int numEntries;
- int maxSize;
-};
-
-SymbolTable *
-createSymbolTable()
-{
- SymbolTable *tab;
-
- tab = (SymbolTable *)malloc(sizeof(SymbolTable));
- if (tab != NULL) {
- tab->numEntries = 0;
- tab->maxSize = DEFAULT_TABLE_SIZE;
- tab->table = (SymbolTableEntry *)malloc(
- tab->maxSize * sizeof(SymbolTableEntry));
- if (tab->table == NULL) {
- free(tab);
- tab = NULL;
- }
- }
- return tab;
-}
-
-void
-deleteSymbolTable(SymbolTable *tab)
-{
- if (tab != NULL) {
- while (tab->numEntries > 0) {
- free(tab->table[--tab->numEntries].symbol);
- }
- free(tab->table);
- }
-}
-
-void *
-findInSymbolTable(SymbolTable *tab, const char *symbol, unsigned int flags)
-{
- int i;
-
- if (tab == NULL || symbol == NULL) {
- return NULL;
- }
-
- // TODO: Sort the table and binary search
- for (i = 0; i < tab->numEntries; i++) {
- if (strcmp(tab->table[i].symbol, symbol) == 0 &&
- tab->table[i].flags == flags)
- {
- return (void *)tab->table[i].cookie;
- }
- }
-
- return NULL;
-}
-
-int
-addToSymbolTable(SymbolTable *tab, const char *symbol, unsigned int flags,
- const void *cookie)
-{
- if (tab == NULL || symbol == NULL || cookie == NULL) {
- return -1;
- }
-
- /* Make sure that this symbol isn't already in the table.
- */
- if (findInSymbolTable(tab, symbol, flags) != NULL) {
- return -2;
- }
-
- /* Make sure there's enough space for the new entry.
- */
- if (tab->numEntries == tab->maxSize) {
- SymbolTableEntry *newTable;
- int newSize;
-
- newSize = tab->numEntries * 2;
- if (newSize < DEFAULT_TABLE_SIZE) {
- newSize = DEFAULT_TABLE_SIZE;
- }
- newTable = (SymbolTableEntry *)realloc(tab->table,
- newSize * sizeof(SymbolTableEntry));
- if (newTable == NULL) {
- return -1;
- }
- tab->maxSize = newSize;
- tab->table = newTable;
- }
-
- /* Insert the new entry.
- */
- symbol = strdup(symbol);
- if (symbol == NULL) {
- return -1;
- }
- // TODO: Sort the table
- tab->table[tab->numEntries].symbol = (char *)symbol;
- tab->table[tab->numEntries].cookie = cookie;
- tab->table[tab->numEntries].flags = flags;
- tab->numEntries++;
-
- return 0;
-}
diff --git a/amend/symtab.h b/amend/symtab.h
deleted file mode 100644
index f83c65b..0000000
--- a/amend/symtab.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 AMEND_SYMTAB_H_
-#define AMEND_SYMTAB_H_
-
-typedef struct SymbolTable SymbolTable;
-
-SymbolTable *createSymbolTable(void);
-
-void deleteSymbolTable(SymbolTable *tab);
-
-/* symbol and cookie must be non-NULL.
- */
-int addToSymbolTable(SymbolTable *tab, const char *symbol, unsigned int flags,
- const void *cookie);
-
-void *findInSymbolTable(SymbolTable *tab, const char *symbol,
- unsigned int flags);
-
-#endif // AMEND_SYMTAB_H_
diff --git a/amend/test_commands.c b/amend/test_commands.c
deleted file mode 100644
index 452f808..0000000
--- a/amend/test_commands.c
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#undef NDEBUG
-#include <assert.h>
-#include "commands.h"
-
-static struct {
- bool called;
- const char *name;
- void *cookie;
- int argc;
- const char **argv;
- int returnValue;
- char *functionResult;
-} gTestCommandState;
-
-static int
-testCommand(const char *name, void *cookie, int argc, const char *argv[])
-{
- gTestCommandState.called = true;
- gTestCommandState.name = name;
- gTestCommandState.cookie = cookie;
- gTestCommandState.argc = argc;
- gTestCommandState.argv = argv;
- return gTestCommandState.returnValue;
-}
-
-static int
-testFunction(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- gTestCommandState.called = true;
- gTestCommandState.name = name;
- gTestCommandState.cookie = cookie;
- gTestCommandState.argc = argc;
- gTestCommandState.argv = argv;
- if (result != NULL) {
- *result = gTestCommandState.functionResult;
- if (resultLen != NULL) {
- *resultLen = strlen(*result);
- }
- }
- return gTestCommandState.returnValue;
-}
-
-static int
-test_commands()
-{
- Command *cmd;
- int ret;
- CommandArgumentType argType;
-
- ret = commandInit();
- assert(ret == 0);
-
- /* Make sure we can't initialize twice.
- */
- ret = commandInit();
- assert(ret < 0);
-
- /* Try calling with some bad values.
- */
- ret = registerCommand(NULL, CMD_ARGS_UNKNOWN, NULL, NULL);
- assert(ret < 0);
-
- ret = registerCommand("hello", CMD_ARGS_UNKNOWN, NULL, NULL);
- assert(ret < 0);
-
- ret = registerCommand("hello", CMD_ARGS_WORDS, NULL, NULL);
- assert(ret < 0);
-
- cmd = findCommand(NULL);
- assert(cmd == NULL);
-
- argType = getCommandArgumentType(NULL);
- assert((int)argType < 0);
-
- ret = callCommand(NULL, -1, NULL);
- assert(ret < 0);
-
- ret = callBooleanCommand(NULL, false);
- assert(ret < 0);
-
- /* Register some commands.
- */
- ret = registerCommand("one", CMD_ARGS_WORDS, testCommand,
- &gTestCommandState);
- assert(ret == 0);
-
- ret = registerCommand("two", CMD_ARGS_WORDS, testCommand,
- &gTestCommandState);
- assert(ret == 0);
-
- ret = registerCommand("bool", CMD_ARGS_BOOLEAN, testCommand,
- &gTestCommandState);
- assert(ret == 0);
-
- /* Make sure that all of those commands exist and that their
- * argument types are correct.
- */
- cmd = findCommand("one");
- assert(cmd != NULL);
- argType = getCommandArgumentType(cmd);
- assert(argType == CMD_ARGS_WORDS);
-
- cmd = findCommand("two");
- assert(cmd != NULL);
- argType = getCommandArgumentType(cmd);
- assert(argType == CMD_ARGS_WORDS);
-
- cmd = findCommand("bool");
- assert(cmd != NULL);
- argType = getCommandArgumentType(cmd);
- assert(argType == CMD_ARGS_BOOLEAN);
-
- /* Make sure that no similar commands exist.
- */
- cmd = findCommand("on");
- assert(cmd == NULL);
-
- cmd = findCommand("onee");
- assert(cmd == NULL);
-
- /* Make sure that a double insertion fails.
- */
- ret = registerCommand("one", CMD_ARGS_WORDS, testCommand,
- &gTestCommandState);
- assert(ret < 0);
-
- /* Make sure that bad args fail.
- */
- cmd = findCommand("one");
- assert(cmd != NULL);
-
- ret = callCommand(cmd, -1, NULL); // argc must be non-negative
- assert(ret < 0);
-
- ret = callCommand(cmd, 1, NULL); // argv can't be NULL if argc > 0
- assert(ret < 0);
-
- /* Make sure that you can't make a boolean call on a regular command.
- */
- cmd = findCommand("one");
- assert(cmd != NULL);
-
- ret = callBooleanCommand(cmd, false);
- assert(ret < 0);
-
- /* Make sure that you can't make a regular call on a boolean command.
- */
- cmd = findCommand("bool");
- assert(cmd != NULL);
-
- ret = callCommand(cmd, 0, NULL);
- assert(ret < 0);
-
- /* Set up some arguments.
- */
- int argc = 4;
- const char *argv[4] = { "ONE", "TWO", "THREE", "FOUR" };
-
- /* Make a call and make sure that it occurred.
- */
- cmd = findCommand("one");
- assert(cmd != NULL);
- memset(&gTestCommandState, 0, sizeof(gTestCommandState));
- gTestCommandState.called = false;
- gTestCommandState.returnValue = 25;
- ret = callCommand(cmd, argc, argv);
-//xxx also try calling with a null argv element (should fail)
- assert(ret == 25);
- assert(gTestCommandState.called);
- assert(strcmp(gTestCommandState.name, "one") == 0);
- assert(gTestCommandState.cookie == &gTestCommandState);
- assert(gTestCommandState.argc == argc);
- assert(gTestCommandState.argv == argv);
-
- /* Make a boolean call and make sure that it occurred.
- */
- cmd = findCommand("bool");
- assert(cmd != NULL);
-
- memset(&gTestCommandState, 0, sizeof(gTestCommandState));
- gTestCommandState.called = false;
- gTestCommandState.returnValue = 12;
- ret = callBooleanCommand(cmd, false);
- assert(ret == 12);
- assert(gTestCommandState.called);
- assert(strcmp(gTestCommandState.name, "bool") == 0);
- assert(gTestCommandState.cookie == &gTestCommandState);
- assert(gTestCommandState.argc == 0);
- assert(gTestCommandState.argv == NULL);
-
- memset(&gTestCommandState, 0, sizeof(gTestCommandState));
- gTestCommandState.called = false;
- gTestCommandState.returnValue = 13;
- ret = callBooleanCommand(cmd, true);
- assert(ret == 13);
- assert(gTestCommandState.called);
- assert(strcmp(gTestCommandState.name, "bool") == 0);
- assert(gTestCommandState.cookie == &gTestCommandState);
- assert(gTestCommandState.argc == 1);
- assert(gTestCommandState.argv == NULL);
-
- /* Smoke test commandCleanup().
- */
- commandCleanup();
-
- return 0;
-}
-
-static int
-test_functions()
-{
- Function *fn;
- int ret;
-
- ret = commandInit();
- assert(ret == 0);
-
- /* Try calling with some bad values.
- */
- ret = registerFunction(NULL, NULL, NULL);
- assert(ret < 0);
-
- ret = registerFunction("hello", NULL, NULL);
- assert(ret < 0);
-
- fn = findFunction(NULL);
- assert(fn == NULL);
-
- ret = callFunction(NULL, -1, NULL, NULL, NULL);
- assert(ret < 0);
-
- /* Register some functions.
- */
- ret = registerFunction("one", testFunction, &gTestCommandState);
- assert(ret == 0);
-
- ret = registerFunction("two", testFunction, &gTestCommandState);
- assert(ret == 0);
-
- ret = registerFunction("three", testFunction, &gTestCommandState);
- assert(ret == 0);
-
- /* Make sure that all of those functions exist.
- * argument types are correct.
- */
- fn = findFunction("one");
- assert(fn != NULL);
-
- fn = findFunction("two");
- assert(fn != NULL);
-
- fn = findFunction("three");
- assert(fn != NULL);
-
- /* Make sure that no similar functions exist.
- */
- fn = findFunction("on");
- assert(fn == NULL);
-
- fn = findFunction("onee");
- assert(fn == NULL);
-
- /* Make sure that a double insertion fails.
- */
- ret = registerFunction("one", testFunction, &gTestCommandState);
- assert(ret < 0);
-
- /* Make sure that bad args fail.
- */
- fn = findFunction("one");
- assert(fn != NULL);
-
- // argc must be non-negative
- ret = callFunction(fn, -1, NULL, (char **)1, NULL);
- assert(ret < 0);
-
- // argv can't be NULL if argc > 0
- ret = callFunction(fn, 1, NULL, (char **)1, NULL);
- assert(ret < 0);
-
- // result can't be NULL
- ret = callFunction(fn, 0, NULL, NULL, NULL);
- assert(ret < 0);
-
- /* Set up some arguments.
- */
- int argc = 4;
- const char *argv[4] = { "ONE", "TWO", "THREE", "FOUR" };
-
- /* Make a call and make sure that it occurred.
- */
- char *functionResult;
- size_t functionResultLen;
- fn = findFunction("one");
- assert(fn != NULL);
- memset(&gTestCommandState, 0, sizeof(gTestCommandState));
- gTestCommandState.called = false;
- gTestCommandState.returnValue = 25;
- gTestCommandState.functionResult = "1234";
- functionResult = NULL;
- functionResultLen = 55;
- ret = callFunction(fn, argc, argv,
- &functionResult, &functionResultLen);
-//xxx also try calling with a null resultLen arg (should succeed)
-//xxx also try calling with a null argv element (should fail)
- assert(ret == 25);
- assert(gTestCommandState.called);
- assert(strcmp(gTestCommandState.name, "one") == 0);
- assert(gTestCommandState.cookie == &gTestCommandState);
- assert(gTestCommandState.argc == argc);
- assert(gTestCommandState.argv == argv);
- assert(strcmp(functionResult, "1234") == 0);
- assert(functionResultLen == strlen(functionResult));
-
- /* Smoke test commandCleanup().
- */
- commandCleanup();
-
- return 0;
-}
-
-static int
-test_interaction()
-{
- Command *cmd;
- Function *fn;
- int ret;
-
- ret = commandInit();
- assert(ret == 0);
-
- /* Register some commands.
- */
- ret = registerCommand("one", CMD_ARGS_WORDS, testCommand, (void *)0xc1);
- assert(ret == 0);
-
- ret = registerCommand("two", CMD_ARGS_WORDS, testCommand, (void *)0xc2);
- assert(ret == 0);
-
- /* Register some functions, one of which shares a name with a command.
- */
- ret = registerFunction("one", testFunction, (void *)0xf1);
- assert(ret == 0);
-
- ret = registerFunction("three", testFunction, (void *)0xf3);
- assert(ret == 0);
-
- /* Look up each of the commands, and make sure no command exists
- * with the name used only by our function.
- */
- cmd = findCommand("one");
- assert(cmd != NULL);
-
- cmd = findCommand("two");
- assert(cmd != NULL);
-
- cmd = findCommand("three");
- assert(cmd == NULL);
-
- /* Look up each of the functions, and make sure no function exists
- * with the name used only by our command.
- */
- fn = findFunction("one");
- assert(fn != NULL);
-
- fn = findFunction("two");
- assert(fn == NULL);
-
- fn = findFunction("three");
- assert(fn != NULL);
-
- /* Set up some arguments.
- */
- int argc = 4;
- const char *argv[4] = { "ONE", "TWO", "THREE", "FOUR" };
-
- /* Call the overlapping command and make sure that the cookie is correct.
- */
- cmd = findCommand("one");
- assert(cmd != NULL);
- memset(&gTestCommandState, 0, sizeof(gTestCommandState));
- gTestCommandState.called = false;
- gTestCommandState.returnValue = 123;
- ret = callCommand(cmd, argc, argv);
- assert(ret == 123);
- assert(gTestCommandState.called);
- assert(strcmp(gTestCommandState.name, "one") == 0);
- assert((int)gTestCommandState.cookie == 0xc1);
- assert(gTestCommandState.argc == argc);
- assert(gTestCommandState.argv == argv);
-
- /* Call the overlapping function and make sure that the cookie is correct.
- */
- char *functionResult;
- size_t functionResultLen;
- fn = findFunction("one");
- assert(fn != NULL);
- memset(&gTestCommandState, 0, sizeof(gTestCommandState));
- gTestCommandState.called = false;
- gTestCommandState.returnValue = 125;
- gTestCommandState.functionResult = "5678";
- functionResult = NULL;
- functionResultLen = 66;
- ret = callFunction(fn, argc, argv, &functionResult, &functionResultLen);
- assert(ret == 125);
- assert(gTestCommandState.called);
- assert(strcmp(gTestCommandState.name, "one") == 0);
- assert((int)gTestCommandState.cookie == 0xf1);
- assert(gTestCommandState.argc == argc);
- assert(gTestCommandState.argv == argv);
- assert(strcmp(functionResult, "5678") == 0);
- assert(functionResultLen == strlen(functionResult));
-
- /* Clean up.
- */
- commandCleanup();
-
- return 0;
-}
-
-int
-test_cmd_fn()
-{
- int ret;
-
- ret = test_commands();
- if (ret != 0) {
- fprintf(stderr, "test_commands() failed: %d\n", ret);
- return ret;
- }
-
- ret = test_functions();
- if (ret != 0) {
- fprintf(stderr, "test_functions() failed: %d\n", ret);
- return ret;
- }
-
- ret = test_interaction();
- if (ret != 0) {
- fprintf(stderr, "test_interaction() failed: %d\n", ret);
- return ret;
- }
-
- return 0;
-}
diff --git a/amend/test_symtab.c b/amend/test_symtab.c
deleted file mode 100644
index 017d18c..0000000
--- a/amend/test_symtab.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 <stdlib.h>
-#undef NDEBUG
-#include <assert.h>
-#include "symtab.h"
-
-int
-test_symtab()
-{
- SymbolTable *tab;
- void *cookie;
- int ret;
-
- /* Test creation */
- tab = createSymbolTable();
- assert(tab != NULL);
-
- /* Smoke-test deletion */
- deleteSymbolTable(tab);
-
-
- tab = createSymbolTable();
- assert(tab != NULL);
-
-
- /* table parameter must be non-NULL. */
- ret = addToSymbolTable(NULL, NULL, 0, NULL);
- assert(ret < 0);
-
- /* symbol parameter must be non-NULL. */
- ret = addToSymbolTable(tab, NULL, 0, NULL);
- assert(ret < 0);
-
- /* cookie parameter must be non-NULL. */
- ret = addToSymbolTable(tab, "null", 0, NULL);
- assert(ret < 0);
-
-
- /* table parameter must be non-NULL. */
- cookie = findInSymbolTable(NULL, NULL, 0);
- assert(cookie == NULL);
-
- /* symbol parameter must be non-NULL. */
- cookie = findInSymbolTable(tab, NULL, 0);
- assert(cookie == NULL);
-
-
- /* Try some actual inserts.
- */
- ret = addToSymbolTable(tab, "one", 0, (void *)1);
- assert(ret == 0);
-
- ret = addToSymbolTable(tab, "two", 0, (void *)2);
- assert(ret == 0);
-
- ret = addToSymbolTable(tab, "three", 0, (void *)3);
- assert(ret == 0);
-
- /* Try some lookups.
- */
- cookie = findInSymbolTable(tab, "one", 0);
- assert((int)cookie == 1);
-
- cookie = findInSymbolTable(tab, "two", 0);
- assert((int)cookie == 2);
-
- cookie = findInSymbolTable(tab, "three", 0);
- assert((int)cookie == 3);
-
- /* Try to insert something that's already there.
- */
- ret = addToSymbolTable(tab, "one", 0, (void *)1111);
- assert(ret < 0);
-
- /* Make sure that the failed duplicate insert didn't
- * clobber the original cookie value.
- */
- cookie = findInSymbolTable(tab, "one", 0);
- assert((int)cookie == 1);
-
- /* Try looking up something that isn't there.
- */
- cookie = findInSymbolTable(tab, "FOUR", 0);
- assert(cookie == NULL);
-
- /* Try looking up something that's similar to an existing entry.
- */
- cookie = findInSymbolTable(tab, "on", 0);
- assert(cookie == NULL);
-
- cookie = findInSymbolTable(tab, "onee", 0);
- assert(cookie == NULL);
-
- /* Test flags.
- * Try inserting something with a different flag.
- */
- ret = addToSymbolTable(tab, "ten", 333, (void *)10);
- assert(ret == 0);
-
- /* Make sure it's there.
- */
- cookie = findInSymbolTable(tab, "ten", 333);
- assert((int)cookie == 10);
-
- /* Make sure it's not there when looked up with a different flag.
- */
- cookie = findInSymbolTable(tab, "ten", 0);
- assert(cookie == NULL);
-
- /* Try inserting something that has the same name as something
- * with a different flag.
- */
- ret = addToSymbolTable(tab, "one", 333, (void *)11);
- assert(ret == 0);
-
- /* Make sure the new entry exists.
- */
- cookie = findInSymbolTable(tab, "one", 333);
- assert((int)cookie == 11);
-
- /* Make sure the old entry still has the right value.
- */
- cookie = findInSymbolTable(tab, "one", 0);
- assert((int)cookie == 1);
-
- /* Try deleting again, now that there's stuff in the table.
- */
- deleteSymbolTable(tab);
-
- return 0;
-}
diff --git a/amend/tests/001-nop/expected.txt b/amend/tests/001-nop/expected.txt
deleted file mode 100644
index d4a85ce..0000000
--- a/amend/tests/001-nop/expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-I am a jelly donut.
diff --git a/amend/tests/001-nop/info.txt b/amend/tests/001-nop/info.txt
deleted file mode 100644
index 9942f10..0000000
--- a/amend/tests/001-nop/info.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-This is a sample no-op test, which does at least serve to verify that the
-test harness is working.
diff --git a/amend/tests/001-nop/run b/amend/tests/001-nop/run
deleted file mode 100644
index 51637c1..0000000
--- a/amend/tests/001-nop/run
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# 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.
-
-echo 'I am a jelly donut.'
diff --git a/amend/tests/002-lex-empty/SKIP b/amend/tests/002-lex-empty/SKIP
deleted file mode 100644
index e69de29..0000000
--- a/amend/tests/002-lex-empty/SKIP
+++ /dev/null
diff --git a/amend/tests/002-lex-empty/expected.txt b/amend/tests/002-lex-empty/expected.txt
deleted file mode 100644
index 822a54c..0000000
--- a/amend/tests/002-lex-empty/expected.txt
+++ /dev/null
@@ -1 +0,0 @@
- EOF
diff --git a/amend/tests/002-lex-empty/info.txt b/amend/tests/002-lex-empty/info.txt
deleted file mode 100644
index 090083f..0000000
--- a/amend/tests/002-lex-empty/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test to make sure that an empty file is accepted properly.
diff --git a/amend/tests/002-lex-empty/input b/amend/tests/002-lex-empty/input
deleted file mode 100644
index e69de29..0000000
--- a/amend/tests/002-lex-empty/input
+++ /dev/null
diff --git a/amend/tests/002-lex-empty/run b/amend/tests/002-lex-empty/run
deleted file mode 100644
index 35c4a4f..0000000
--- a/amend/tests/002-lex-empty/run
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# 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.
-
-amend --debug-lex input
diff --git a/amend/tests/003-lex-command/expected.txt b/amend/tests/003-lex-command/expected.txt
deleted file mode 100644
index e40db0c..0000000
--- a/amend/tests/003-lex-command/expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
- IDENTIFIER<this_identifier_is_not_assert> EOL
- IDENTIFIER<NEITHER_IS_THIS_123> EOL
- IDENTIFIER<but_the_next_one_is> EOL
- IDENTIFIER<assert> EOL
- IDENTIFIER<next_one_is_not_an_identifier> EOL
-line 6: unexpected character at '1'
- EOF
-line 1: unexpected character at '"'
- EOF
-line 1: unexpected character at '='
- EOF
-line 1: unexpected character at '9'
- EOF
diff --git a/amend/tests/003-lex-command/info.txt b/amend/tests/003-lex-command/info.txt
deleted file mode 100644
index 9296648..0000000
--- a/amend/tests/003-lex-command/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test to make sure that simple command names are tokenized properly.
diff --git a/amend/tests/003-lex-command/input b/amend/tests/003-lex-command/input
deleted file mode 100644
index b9ef231..0000000
--- a/amend/tests/003-lex-command/input
+++ /dev/null
@@ -1,6 +0,0 @@
-this_identifier_is_not_assert
-NEITHER_IS_THIS_123
-but_the_next_one_is
-assert
-next_one_is_not_an_identifier
-12not_an_identifier
diff --git a/amend/tests/003-lex-command/input2 b/amend/tests/003-lex-command/input2
deleted file mode 100644
index eb5daf7..0000000
--- a/amend/tests/003-lex-command/input2
+++ /dev/null
@@ -1 +0,0 @@
-"quoted"
diff --git a/amend/tests/003-lex-command/input3 b/amend/tests/003-lex-command/input3
deleted file mode 100644
index f1c8738..0000000
--- a/amend/tests/003-lex-command/input3
+++ /dev/null
@@ -1 +0,0 @@
-==
diff --git a/amend/tests/003-lex-command/input4 b/amend/tests/003-lex-command/input4
deleted file mode 100644
index 3ad5abd..0000000
--- a/amend/tests/003-lex-command/input4
+++ /dev/null
@@ -1 +0,0 @@
-99
diff --git a/amend/tests/003-lex-command/run b/amend/tests/003-lex-command/run
deleted file mode 100644
index 2e21fab..0000000
--- a/amend/tests/003-lex-command/run
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# 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.
-
-amend --debug-lex input
-amend --debug-lex input2
-amend --debug-lex input3
-amend --debug-lex input4
diff --git a/amend/tests/004-lex-comment/expected.txt b/amend/tests/004-lex-comment/expected.txt
deleted file mode 100644
index a728a5e..0000000
--- a/amend/tests/004-lex-comment/expected.txt
+++ /dev/null
@@ -1,5 +0,0 @@
- IDENTIFIER<comment_on_this_line> EOL
- IDENTIFIER<none_on_this_one> EOL
- EOL
- EOL
- EOF
diff --git a/amend/tests/004-lex-comment/info.txt b/amend/tests/004-lex-comment/info.txt
deleted file mode 100644
index 0691248..0000000
--- a/amend/tests/004-lex-comment/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test to make sure that comments are stripped out.
diff --git a/amend/tests/004-lex-comment/input b/amend/tests/004-lex-comment/input
deleted file mode 100644
index 6736c95..0000000
--- a/amend/tests/004-lex-comment/input
+++ /dev/null
@@ -1,4 +0,0 @@
-comment_on_this_line # this is a "comment" (with / a bunch) # \\ of stuff \
-none_on_this_one
-# beginning of line
- # preceded by whitespace
diff --git a/amend/tests/004-lex-comment/run b/amend/tests/004-lex-comment/run
deleted file mode 100644
index 35c4a4f..0000000
--- a/amend/tests/004-lex-comment/run
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# 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.
-
-amend --debug-lex input
diff --git a/amend/tests/005-lex-quoted-string/expected.txt b/amend/tests/005-lex-quoted-string/expected.txt
deleted file mode 100644
index 9bb5ac4..0000000
--- a/amend/tests/005-lex-quoted-string/expected.txt
+++ /dev/null
@@ -1,13 +0,0 @@
- IDENTIFIER<test> WORD<string> EOL
- IDENTIFIER<test> WORD<string with spaces> EOL
- IDENTIFIER<test> WORD<string with "escaped" quotes> EOL
- IDENTIFIER<test> WORD<string with \escaped\ backslashes> EOL
- IDENTIFIER<test> WORD<string with # a comment character> EOL
- EOF
- EOL
- IDENTIFIER<test1>line 2: unterminated string at '
-'
- ??? <0>
- EOL
- IDENTIFIER<test1>line 2: illegal escape at '\n'
- ??? <0>
diff --git a/amend/tests/005-lex-quoted-string/info.txt b/amend/tests/005-lex-quoted-string/info.txt
deleted file mode 100644
index be458bd..0000000
--- a/amend/tests/005-lex-quoted-string/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test to make sure that quoted strings are tokenized properly.
diff --git a/amend/tests/005-lex-quoted-string/input b/amend/tests/005-lex-quoted-string/input
deleted file mode 100644
index 2b34bbc..0000000
--- a/amend/tests/005-lex-quoted-string/input
+++ /dev/null
@@ -1,5 +0,0 @@
-test "string"
-test "string with spaces"
-test "string with \"escaped\" quotes"
-test "string with \\escaped\\ backslashes"
-test "string with # a comment character"
diff --git a/amend/tests/005-lex-quoted-string/input2 b/amend/tests/005-lex-quoted-string/input2
deleted file mode 100644
index 09e6689..0000000
--- a/amend/tests/005-lex-quoted-string/input2
+++ /dev/null
@@ -1,2 +0,0 @@
-# This should fail
-test1 "unterminated string
diff --git a/amend/tests/005-lex-quoted-string/input3 b/amend/tests/005-lex-quoted-string/input3
deleted file mode 100644
index 02f3f85..0000000
--- a/amend/tests/005-lex-quoted-string/input3
+++ /dev/null
@@ -1,2 +0,0 @@
-# This should fail
-test1 "string with illegal escape \n in the middle"
diff --git a/amend/tests/005-lex-quoted-string/run b/amend/tests/005-lex-quoted-string/run
deleted file mode 100644
index 7b1292a..0000000
--- a/amend/tests/005-lex-quoted-string/run
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# 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.
-
-amend --debug-lex input
-amend --debug-lex input2
-amend --debug-lex input3
diff --git a/amend/tests/006-lex-words/SKIP b/amend/tests/006-lex-words/SKIP
deleted file mode 100644
index e69de29..0000000
--- a/amend/tests/006-lex-words/SKIP
+++ /dev/null
diff --git a/amend/tests/006-lex-words/expected.txt b/amend/tests/006-lex-words/expected.txt
deleted file mode 100644
index a78a0b1..0000000
--- a/amend/tests/006-lex-words/expected.txt
+++ /dev/null
@@ -1,6 +0,0 @@
- IDENTIFIER<test> WORD<this> WORD<has> WORD<a> WORD<bunch> WORD<of> WORD<BARE> WORD<ALPHA> WORD<WORDS> EOL
- IDENTIFIER<test> WORD<12> WORD<this> WORD<has(some> WORD<)> WORD<ALPHANUMER1C> WORD<and> WORD<\\> WORD<whatever> WORD<characters> EOL
- IDENTIFIER<test> WORD<this> WORD<has> WORD<mixed> WORD<bare> WORD<and quoted> WORD<words> EOL
- IDENTIFIER<test> WORD<what> WORD<about> WORD<quotesin the middle?> EOL
- IDENTIFIER<test> WORD<"""shouldn't> WORD<be> WORD<a> WORD<quoted> WORD<string> EOL
- EOF
diff --git a/amend/tests/006-lex-words/info.txt b/amend/tests/006-lex-words/info.txt
deleted file mode 100644
index dd37016..0000000
--- a/amend/tests/006-lex-words/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-Test to make sure that argument words are tokenized properly.
diff --git a/amend/tests/006-lex-words/input b/amend/tests/006-lex-words/input
deleted file mode 100644
index a4de638..0000000
--- a/amend/tests/006-lex-words/input
+++ /dev/null
@@ -1,5 +0,0 @@
-test this has a bunch of BARE ALPHA WORDS
-test 12 this has(some ) ALPHANUMER1C and \\ whatever characters
-test this has mixed bare "and quoted" words
-test what about quotes"in the middle?"
-test \"\"\"shouldn't be a quoted string
diff --git a/amend/tests/006-lex-words/input2 b/amend/tests/006-lex-words/input2
deleted file mode 100644
index 09e6689..0000000
--- a/amend/tests/006-lex-words/input2
+++ /dev/null
@@ -1,2 +0,0 @@
-# This should fail
-test1 "unterminated string
diff --git a/amend/tests/006-lex-words/input3 b/amend/tests/006-lex-words/input3
deleted file mode 100644
index 02f3f85..0000000
--- a/amend/tests/006-lex-words/input3
+++ /dev/null
@@ -1,2 +0,0 @@
-# This should fail
-test1 "string with illegal escape \n in the middle"
diff --git a/amend/tests/006-lex-words/run b/amend/tests/006-lex-words/run
deleted file mode 100644
index 35c4a4f..0000000
--- a/amend/tests/006-lex-words/run
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# 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.
-
-amend --debug-lex input
diff --git a/amend/tests/007-lex-real-script/expected.txt b/amend/tests/007-lex-real-script/expected.txt
deleted file mode 100644
index 012f62c..0000000
--- a/amend/tests/007-lex-real-script/expected.txt
+++ /dev/null
@@ -1,11 +0,0 @@
- IDENTIFIER<assert> IDENTIFIER<hash_dir> ( STRING<SYS:> ) == STRING<112345oldhashvalue1234123> EOL
- IDENTIFIER<mark> WORD<SYS:> WORD<dirty> EOL
- IDENTIFIER<copy_dir> WORD<PKG:android-files> WORD<SYS:> EOL
- IDENTIFIER<assert> IDENTIFIER<hash_dir> ( STRING<SYS:> ) == STRING<667890newhashvalue6678909> EOL
- IDENTIFIER<mark> WORD<SYS:> WORD<clean> EOL
- IDENTIFIER<done> EOL
- IDENTIFIER<assert> IDENTIFIER<hash_dir> ( STRING<SYS:> , STRING<blah> ) == STRING<112345oldhashvalue1234123> EOL
- IDENTIFIER<assert> STRING<true> == STRING<false> EOL
- IDENTIFIER<assert> IDENTIFIER<one> ( STRING<abc> , IDENTIFIER<two> ( STRING<def> ) ) == STRING<five> EOL
- IDENTIFIER<assert> IDENTIFIER<hash_dir> ( STRING<SYS:> ) == STRING<667890newhashvalue6678909> || IDENTIFIER<hash_dir> ( STRING<SYS:> ) == STRING<667890newhashvalue6678909> EOL
- EOF
diff --git a/amend/tests/007-lex-real-script/info.txt b/amend/tests/007-lex-real-script/info.txt
deleted file mode 100644
index 5e321f5..0000000
--- a/amend/tests/007-lex-real-script/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-An input script similar to one that will actually be used in practice.
diff --git a/amend/tests/007-lex-real-script/input b/amend/tests/007-lex-real-script/input
deleted file mode 100644
index f3f1fd9..0000000
--- a/amend/tests/007-lex-real-script/input
+++ /dev/null
@@ -1,10 +0,0 @@
-assert hash_dir("SYS:") == "112345oldhashvalue1234123"
-mark SYS: dirty
-copy_dir "PKG:android-files" SYS:
-assert hash_dir("SYS:") == "667890newhashvalue6678909"
-mark SYS: clean
-done
-assert hash_dir("SYS:", "blah") == "112345oldhashvalue1234123"
-assert "true" == "false"
-assert one("abc", two("def")) == "five"
-assert hash_dir("SYS:") == "667890newhashvalue6678909" || hash_dir("SYS:") == "667890newhashvalue6678909"
diff --git a/amend/tests/007-lex-real-script/run b/amend/tests/007-lex-real-script/run
deleted file mode 100644
index 35c4a4f..0000000
--- a/amend/tests/007-lex-real-script/run
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# 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.
-
-amend --debug-lex input
diff --git a/amend/tests/008-parse-real-script/expected.txt b/amend/tests/008-parse-real-script/expected.txt
deleted file mode 100644
index dabf6d4..0000000
--- a/amend/tests/008-parse-real-script/expected.txt
+++ /dev/null
@@ -1,74 +0,0 @@
-command "assert" {
- STRING EQ {
- FUNCTION hash_dir (
- "SYS:"
- )
- "112345oldhashvalue1234123"
- }
-}
-command "mark" {
- "SYS:"
- "dirty"
-}
-command "copy_dir" {
- "PKG:android-files"
- "SYS:"
-}
-command "assert" {
- STRING EQ {
- FUNCTION hash_dir (
- "SYS:"
- )
- "667890newhashvalue6678909"
- }
-}
-command "mark" {
- "SYS:"
- "clean"
-}
-command "done" {
-}
-command "assert" {
- STRING EQ {
- FUNCTION hash_dir (
- "SYS:"
- "blah"
- )
- "112345oldhashvalue1234123"
- }
-}
-command "assert" {
- STRING EQ {
- "true"
- "false"
- }
-}
-command "assert" {
- STRING NE {
- FUNCTION matches (
- FUNCTION hash_dir (
- "SYS:"
- )
- "667890newhashvalue6678909"
- "999999newhashvalue6678909"
- )
- ""
- }
-}
-command "assert" {
- BOOLEAN OR {
- STRING EQ {
- FUNCTION hash_dir (
- "SYS:"
- )
- "667890newhashvalue6678909"
- }
- STRING EQ {
- FUNCTION hash_dir (
- "SYS:"
- )
- "999999newhashvalue6678909"
- }
- }
-}
-amend: Parse successful.
diff --git a/amend/tests/008-parse-real-script/info.txt b/amend/tests/008-parse-real-script/info.txt
deleted file mode 100644
index 5e321f5..0000000
--- a/amend/tests/008-parse-real-script/info.txt
+++ /dev/null
@@ -1 +0,0 @@
-An input script similar to one that will actually be used in practice.
diff --git a/amend/tests/008-parse-real-script/input b/amend/tests/008-parse-real-script/input
deleted file mode 100644
index b073306..0000000
--- a/amend/tests/008-parse-real-script/input
+++ /dev/null
@@ -1,10 +0,0 @@
-assert hash_dir("SYS:") == "112345oldhashvalue1234123"
-mark SYS: dirty
-copy_dir "PKG:android-files" SYS:
-assert hash_dir("SYS:") == "667890newhashvalue6678909"
-mark SYS: clean
-done
-assert hash_dir("SYS:", "blah") == "112345oldhashvalue1234123"
-assert "true" == "false"
-assert matches(hash_dir("SYS:"), "667890newhashvalue6678909", "999999newhashvalue6678909") != ""
-assert hash_dir("SYS:") == "667890newhashvalue6678909" || hash_dir("SYS:") == "999999newhashvalue6678909"
diff --git a/amend/tests/008-parse-real-script/run b/amend/tests/008-parse-real-script/run
deleted file mode 100644
index 9544e1b..0000000
--- a/amend/tests/008-parse-real-script/run
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# 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.
-
-amend --debug-ast input
diff --git a/amend/tests/XXX-long-token/SKIP b/amend/tests/XXX-long-token/SKIP
deleted file mode 100644
index e69de29..0000000
--- a/amend/tests/XXX-long-token/SKIP
+++ /dev/null
diff --git a/amend/tests/XXX-stack-overflow/SKIP b/amend/tests/XXX-stack-overflow/SKIP
deleted file mode 100644
index e69de29..0000000
--- a/amend/tests/XXX-stack-overflow/SKIP
+++ /dev/null
diff --git a/amend/tests/one-test b/amend/tests/one-test
deleted file mode 100755
index 9cebd3f..0000000
--- a/amend/tests/one-test
+++ /dev/null
@@ -1,150 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# 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.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
- newProg=`/bin/ls -ld "${prog}"`
- newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
- if expr "x${newProg}" : 'x/' >/dev/null; then
- prog="${newProg}"
- else
- progdir=`dirname "${prog}"`
- prog="${progdir}/${newProg}"
- fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-
-info="info.txt"
-run="run"
-expected="expected.txt"
-output="out.txt"
-skip="SKIP"
-
-dev_mode="no"
-if [ "x$1" = "x--dev" ]; then
- dev_mode="yes"
- shift
-fi
-
-update_mode="no"
-if [ "x$1" = "x--update" ]; then
- update_mode="yes"
- shift
-fi
-
-usage="no"
-if [ "x$1" = "x--help" ]; then
- usage="yes"
-else
- if [ "x$1" = "x" ]; then
- testdir=`basename "$oldwd"`
- else
- testdir="$1"
- fi
-
- if [ '!' -d "$testdir" ]; then
- td2=`echo ${testdir}-*`
- if [ '!' -d "$td2" ]; then
- echo "${testdir}: no such test directory" 1>&2
- usage="yes"
- fi
- testdir="$td2"
- fi
-fi
-
-if [ "$usage" = "yes" ]; then
- prog=`basename $prog`
- (
- echo "usage:"
- echo " $prog --help Print this message."
- echo " $prog testname Run test normally."
- echo " $prog --dev testname Development mode (dump to stdout)."
- echo " $prog --update testname Update mode (replace expected.txt)."
- echo " Omitting the test name uses the current directory as the test."
- ) 1>&2
- exit 1
-fi
-
-td_info="$testdir"/"$info"
-td_run="$testdir"/"$run"
-td_expected="$testdir"/"$expected"
-td_skip="$testdir"/"$skip"
-
-if [ -r "$td_skip" ]; then
- exit 2
-fi
-
-tmpdir=/tmp/test-$$
-
-if [ '!' '(' -r "$td_info" -a -r "$td_run" -a -r "$td_expected" ')' ]; then
- echo "${testdir}: missing files" 1>&2
- exit 1
-fi
-
-# copy the test to a temp dir and run it
-
-echo "${testdir}: running..." 1>&2
-
-rm -rf "$tmpdir"
-cp -Rp "$testdir" "$tmpdir"
-cd "$tmpdir"
-chmod 755 "$run"
-
-#PATH="${progdir}/../build/bin:${PATH}"
-
-good="no"
-if [ "$dev_mode" = "yes" ]; then
- "./$run" 2>&1
- echo "exit status: $?" 1>&2
- good="yes"
-elif [ "$update_mode" = "yes" ]; then
- "./$run" >"${progdir}/$td_expected" 2>&1
- good="yes"
-else
- "./$run" >"$output" 2>&1
- cmp -s "$expected" "$output"
- if [ "$?" = "0" ]; then
- # output == expected
- good="yes"
- echo "$testdir"': succeeded!' 1>&2
- fi
-fi
-
-if [ "$good" = "yes" ]; then
- cd "$oldwd"
- rm -rf "$tmpdir"
- exit 0
-fi
-
-(
- echo "${testdir}: FAILED!"
- echo ' '
- echo '#################### info'
- cat "$info" | sed 's/^/# /g'
- echo '#################### diffs'
- diff -u "$expected" "$output"
- echo '####################'
- echo ' '
- echo "files left in $tmpdir"
-) 1>&2
-
-exit 1
diff --git a/amend/tests/run-all-tests b/amend/tests/run-all-tests
deleted file mode 100755
index c696bbd..0000000
--- a/amend/tests/run-all-tests
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/bin/bash
-#
-# Copyright (C) 2007 The Android Open Source Project
-#
-# 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.
-
-# Set up prog to be the path of this script, including following symlinks,
-# and set up progdir to be the fully-qualified pathname of its directory.
-prog="$0"
-while [ -h "${prog}" ]; do
- newProg=`/bin/ls -ld "${prog}"`
- newProg=`expr "${newProg}" : ".* -> \(.*\)$"`
- if expr "x${newProg}" : 'x/' >/dev/null; then
- prog="${newProg}"
- else
- progdir=`dirname "${prog}"`
- prog="${progdir}/${newProg}"
- fi
-done
-oldwd=`pwd`
-progdir=`dirname "${prog}"`
-cd "${progdir}"
-progdir=`pwd`
-prog="${progdir}"/`basename "${prog}"`
-
-passed=0
-skipped=0
-skipNames=""
-failed=0
-failNames=""
-
-for i in *; do
- if [ -d "$i" -a -r "$i" ]; then
- ./one-test "$i"
- status=$?
- if [ "$status" = "0" ]; then
- ((passed += 1))
- elif [ "$status" = "2" ]; then
- ((skipped += 1))
- skipNames="$skipNames $i"
- else
- ((failed += 1))
- failNames="$failNames $i"
- fi
- fi
-done
-
-echo "passed: $passed test(s)"
-echo "skipped: $skipped test(s)"
-
-for i in $skipNames; do
- echo "skipped: $i"
-done
-
-echo "failed: $failed test(s)"
-
-for i in $failNames; do
- echo "failed: $i"
-done
diff --git a/commands.c b/commands.c
deleted file mode 100644
index b4678ba..0000000
--- a/commands.c
+++ /dev/null
@@ -1,1075 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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.
- */
-
-#undef NDEBUG
-
-#include <assert.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <unistd.h>
-
-#include "amend/commands.h"
-#include "commands.h"
-#include "common.h"
-#include "cutils/misc.h"
-#include "cutils/properties.h"
-#include "firmware.h"
-#include "minzip/DirUtil.h"
-#include "minzip/Zip.h"
-#include "roots.h"
-
-static int gDidShowProgress = 0;
-
-#define UNUSED(p) ((void)(p))
-
-#define CHECK_BOOL() \
- do { \
- assert(argv == NULL); \
- if (argv != NULL) return -1; \
- assert(argc == true || argc == false); \
- if (argc != true && argc != false) return -1; \
- } while (false)
-
-#define CHECK_WORDS() \
- do { \
- assert(argc >= 0); \
- if (argc < 0) return -1; \
- assert(argc == 0 || argv != NULL); \
- if (argc != 0 && argv == NULL) return -1; \
- } while (false)
-
-#define CHECK_FN() \
- do { \
- CHECK_WORDS(); \
- assert(result != NULL); \
- if (result == NULL) return -1; \
- } while (false)
-
-/*
- * Command definitions
- */
-
-/* assert <boolexpr>
- */
-static int
-cmd_assert(const char *name, void *cookie, int argc, const char *argv[])
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_BOOL();
-
- /* If our argument is false, return non-zero (failure)
- * If our argument is true, return zero (success)
- */
- if (argc) {
- return 0;
- } else {
- return 1;
- }
-}
-
-/* format <root>
- */
-static int
-cmd_format(const char *name, void *cookie, int argc, const char *argv[])
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_WORDS();
-
- if (argc != 1) {
- LOGE("Command %s requires exactly one argument\n", name);
- return 1;
- }
- const char *root = argv[0];
- ui_print("Formatting %s...\n", root);
-
- int ret = format_root_device(root);
- if (ret != 0) {
- LOGE("Can't format %s\n", root);
- return 1;
- }
-
- return 0;
-}
-
-/* delete <file1> [<fileN> ...]
- * delete_recursive <file-or-dir1> [<file-or-dirN> ...]
- *
- * Like "rm -f", will try to delete every named file/dir, even if
- * earlier ones fail. Recursive deletes that fail halfway through
- * give up early.
- */
-static int
-cmd_delete(const char *name, void *cookie, int argc, const char *argv[])
-{
- UNUSED(cookie);
- CHECK_WORDS();
- int nerr = 0;
- bool recurse;
-
- if (argc < 1) {
- LOGE("Command %s requires at least one argument\n", name);
- return 1;
- }
-
- recurse = (strcmp(name, "delete_recursive") == 0);
- ui_print("Deleting files...\n");
-
- int i;
- for (i = 0; i < argc; i++) {
- const char *root_path = argv[i];
- char pathbuf[PATH_MAX];
- const char *path;
-
- /* This guarantees that all paths use "SYSTEM:"-style roots;
- * plain paths won't make it through translate_root_path().
- */
- path = translate_root_path(root_path, pathbuf, sizeof(pathbuf));
- if (path != NULL) {
- int ret = ensure_root_path_mounted(root_path);
- if (ret < 0) {
- LOGW("Can't mount volume to delete \"%s\"\n", root_path);
- nerr++;
- continue;
- }
- if (recurse) {
- ret = dirUnlinkHierarchy(path);
- } else {
- ret = unlink(path);
- }
- if (ret != 0 && errno != ENOENT) {
- LOGW("Can't delete %s\n(%s)\n", path, strerror(errno));
- nerr++;
- }
- } else {
- nerr++;
- }
- }
-//TODO: add a way to fail if a delete didn't work
-
- return 0;
-}
-
-typedef struct {
- int num_done;
- int num_total;
-} ExtractContext;
-
-static void extract_count_cb(const char *fn, void *cookie)
-{
- ++((ExtractContext*) cookie)->num_total;
-}
-
-static void extract_cb(const char *fn, void *cookie)
-{
- // minzip writes the filename to the log, so we don't need to
- ExtractContext *ctx = (ExtractContext*) cookie;
- ui_set_progress((float) ++ctx->num_done / ctx->num_total);
-}
-
-/* copy_dir <src-dir> <dst-dir> [<timestamp>]
- *
- * The contents of <src-dir> will become the contents of <dst-dir>.
- * The original contents of <dst-dir> are preserved unless something
- * in <src-dir> overwrote them.
- *
- * e.g., for "copy_dir PKG:system SYSTEM:", the file "PKG:system/a"
- * would be copied to "SYSTEM:a".
- *
- * The specified timestamp (in decimal seconds since 1970) will be used,
- * or a fixed default timestamp will be supplied otherwise.
- */
-static int
-cmd_copy_dir(const char *name, void *cookie, int argc, const char *argv[])
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_WORDS();
-
- // To create a consistent system image, never use the clock for timestamps.
- struct utimbuf timestamp = { 1217592000, 1217592000 }; // 8/1/2008 default
- if (argc == 3) {
- char *end;
- time_t value = strtoul(argv[2], &end, 0);
- if (value == 0 || end[0] != '\0') {
- LOGE("Command %s: invalid timestamp \"%s\"\n", name, argv[2]);
- return 1;
- } else if (value < timestamp.modtime) {
- LOGE("Command %s: timestamp \"%s\" too early\n", name, argv[2]);
- return 1;
- }
- timestamp.modtime = timestamp.actime = value;
- } else if (argc != 2) {
- LOGE("Command %s requires exactly two arguments\n", name);
- return 1;
- }
-
- // Use 40% of the progress bar (80% post-verification) by default
- ui_print("Copying files...\n");
- if (!gDidShowProgress) ui_show_progress(DEFAULT_FILES_PROGRESS_FRACTION, 0);
-
- /* Mount the destination volume if it isn't already.
- */
- const char *dst_root_path = argv[1];
- int ret = ensure_root_path_mounted(dst_root_path);
- if (ret < 0) {
- LOGE("Can't mount %s\n", dst_root_path);
- return 1;
- }
-
- /* Get the real target path.
- */
- char dstpathbuf[PATH_MAX];
- const char *dst_path;
- dst_path = translate_root_path(dst_root_path,
- dstpathbuf, sizeof(dstpathbuf));
- if (dst_path == NULL) {
- LOGE("Command %s: bad destination path \"%s\"\n", name, dst_root_path);
- return 1;
- }
-
- /* Try to copy the directory. The source may be inside a package.
- */
- const char *src_root_path = argv[0];
- char srcpathbuf[PATH_MAX];
- const char *src_path;
- if (is_package_root_path(src_root_path)) {
- const ZipArchive *package;
- src_path = translate_package_root_path(src_root_path,
- srcpathbuf, sizeof(srcpathbuf), &package);
- if (src_path == NULL) {
- LOGE("Command %s: bad source path \"%s\"\n", name, src_root_path);
- return 1;
- }
-
- /* Extract the files. Set MZ_EXTRACT_FILES_ONLY, because only files
- * are validated by the signature. Do a dry run first to count how
- * many there are (and find some errors early).
- */
- ExtractContext ctx;
- ctx.num_done = 0;
- ctx.num_total = 0;
-
- if (!mzExtractRecursive(package, src_path, dst_path,
- MZ_EXTRACT_FILES_ONLY | MZ_EXTRACT_DRY_RUN,
- ×tamp, extract_count_cb, (void *) &ctx) ||
- !mzExtractRecursive(package, src_path, dst_path,
- MZ_EXTRACT_FILES_ONLY,
- ×tamp, extract_cb, (void *) &ctx)) {
- LOGW("Command %s: couldn't extract \"%s\" to \"%s\"\n",
- name, src_root_path, dst_root_path);
- return 1;
- }
- } else {
- LOGE("Command %s: non-package source path \"%s\" not yet supported\n",
- name, src_root_path);
-//xxx mount the src volume
-//xxx
- return 255;
- }
-
- return 0;
-}
-
-/* run_program <program-file> [<args> ...]
- *
- * Run an external program included in the update package.
- */
-static int
-cmd_run_program(const char *name, void *cookie, int argc, const char *argv[])
-{
- UNUSED(cookie);
- CHECK_WORDS();
-
- if (argc < 1) {
- LOGE("Command %s requires at least one argument\n", name);
- return 1;
- }
-
- // Copy the program file to temporary storage.
- if (!is_package_root_path(argv[0])) {
- LOGE("Command %s: non-package program file \"%s\" not supported\n",
- name, argv[0]);
- return 1;
- }
-
- char path[PATH_MAX];
- const ZipArchive *package;
- if (!translate_package_root_path(argv[0], path, sizeof(path), &package)) {
- LOGE("Command %s: bad source path \"%s\"\n", name, argv[0]);
- return 1;
- }
-
- const ZipEntry *entry = mzFindZipEntry(package, path);
- if (entry == NULL) {
- LOGE("Can't find %s\n", path);
- return 1;
- }
-
- static const char *binary = "/tmp/run_program_binary";
- unlink(binary); // just to be sure
- int fd = creat(binary, 0755);
- if (fd < 0) {
- LOGE("Can't make %s\n", binary);
- return 1;
- }
- bool ok = mzExtractZipEntryToFile(package, entry, fd);
- close(fd);
-
- if (!ok) {
- LOGE("Can't copy %s\n", path);
- return 1;
- }
-
- // Create a copy of argv to NULL-terminate it, as execv requires
- char **args = (char **) malloc(sizeof(char*) * (argc + 1));
- memcpy(args, argv, sizeof(char*) * argc);
- args[argc] = NULL;
-
- pid_t pid = fork();
- if (pid == 0) {
- execv(binary, args);
- fprintf(stderr, "E:Can't run %s\n(%s)\n", binary, strerror(errno));
- _exit(-1);
- }
-
- int status;
- waitpid(pid, &status, 0);
- if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
- return 0;
- } else {
- LOGE("Error in %s\n(Status %d)\n", path, status);
- return 1;
- }
-}
-
-/* set_perm <uid> <gid> <mode> <path> [... <pathN>]
- * set_perm_recursive <uid> <gid> <dir-mode> <file-mode> <path> [... <pathN>]
- *
- * Like "chmod", "chown" and "chgrp" all in one, set ownership and permissions
- * of single files or entire directory trees. Any error causes failure.
- * User, group, and modes must all be integer values (hex or octal OK).
- */
-static int
-cmd_set_perm(const char *name, void *cookie, int argc, const char *argv[])
-{
- UNUSED(cookie);
- CHECK_WORDS();
- bool recurse = !strcmp(name, "set_perm_recursive");
-
- int min_args = 4 + (recurse ? 1 : 0);
- if (argc < min_args) {
- LOGE("Command %s requires at least %d args\n", name, min_args);
- return 1;
- }
-
- // All the arguments except the path(s) are numeric.
- int i, n[min_args - 1];
- for (i = 0; i < min_args - 1; ++i) {
- char *end;
- n[i] = strtoul(argv[i], &end, 0);
- if (end[0] != '\0' || argv[i][0] == '\0') {
- LOGE("Command %s: invalid argument \"%s\"\n", name, argv[i]);
- return 1;
- }
- }
-
- for (i = min_args - 1; i < min_args; ++i) {
- char path[PATH_MAX];
- if (translate_root_path(argv[i], path, sizeof(path)) == NULL) {
- LOGE("Command %s: bad path \"%s\"\n", name, argv[i]);
- return 1;
- }
-
- if (ensure_root_path_mounted(argv[i])) {
- LOGE("Can't mount %s\n", argv[i]);
- return 1;
- }
-
- if (recurse
- ? dirSetHierarchyPermissions(path, n[0], n[1], n[2], n[3])
- : (chown(path, n[0], n[1]) || chmod(path, n[2]))) {
- LOGE("Can't chown/mod %s\n(%s)\n", path, strerror(errno));
- return 1;
- }
- }
-
- return 0;
-}
-
-/* show_progress <fraction> <duration>
- *
- * Use <fraction> of the on-screen progress meter for the next operation,
- * automatically advancing the meter over <duration> seconds (or more rapidly
- * if the actual rate of progress can be determined).
- */
-static int
-cmd_show_progress(const char *name, void *cookie, int argc, const char *argv[])
-{
- UNUSED(cookie);
- CHECK_WORDS();
-
- if (argc != 2) {
- LOGE("Command %s requires exactly two arguments\n", name);
- return 1;
- }
-
- char *end;
- double fraction = strtod(argv[0], &end);
- if (end[0] != '\0' || argv[0][0] == '\0' || fraction < 0 || fraction > 1) {
- LOGE("Command %s: invalid fraction \"%s\"\n", name, argv[0]);
- return 1;
- }
-
- int duration = strtoul(argv[1], &end, 0);
- if (end[0] != '\0' || argv[0][0] == '\0') {
- LOGE("Command %s: invalid duration \"%s\"\n", name, argv[1]);
- return 1;
- }
-
- // Half of the progress bar is taken by verification,
- // so everything that happens during installation is scaled.
- ui_show_progress(fraction * (1 - VERIFICATION_PROGRESS_FRACTION), duration);
- gDidShowProgress = 1;
- return 0;
-}
-
-/* symlink <link-target> <link-path>
- *
- * Create a symlink, like "ln -s". The link path must not exist already.
- * Note that <link-path> is in root:path format, but <link-target> is
- * for the target filesystem (and may be relative).
- */
-static int
-cmd_symlink(const char *name, void *cookie, int argc, const char *argv[])
-{
- UNUSED(cookie);
- CHECK_WORDS();
-
- if (argc != 2) {
- LOGE("Command %s requires exactly two arguments\n", name);
- return 1;
- }
-
- char path[PATH_MAX];
- if (translate_root_path(argv[1], path, sizeof(path)) == NULL) {
- LOGE("Command %s: bad path \"%s\"\n", name, argv[1]);
- return 1;
- }
-
- if (ensure_root_path_mounted(argv[1])) {
- LOGE("Can't mount %s\n", argv[1]);
- return 1;
- }
-
- if (symlink(argv[0], path)) {
- LOGE("Can't symlink %s\n", path);
- return 1;
- }
-
- return 0;
-}
-
-struct FirmwareContext {
- size_t total_bytes, done_bytes;
- char *data;
-};
-
-static bool firmware_fn(const unsigned char *data, int data_len, void *cookie)
-{
- struct FirmwareContext *context = (struct FirmwareContext*) cookie;
- if (context->done_bytes + data_len > context->total_bytes) {
- LOGE("Data overrun in firmware\n");
- return false; // Should not happen, but let's be safe.
- }
-
- memcpy(context->data + context->done_bytes, data, data_len);
- context->done_bytes += data_len;
- ui_set_progress(context->done_bytes * 1.0 / context->total_bytes);
- return true;
-}
-
-/* write_radio_image <src-image>
- * write_hboot_image <src-image>
- * Doesn't actually take effect until the rest of installation finishes.
- */
-static int
-cmd_write_firmware_image(const char *name, void *cookie,
- int argc, const char *argv[])
-{
- UNUSED(cookie);
- CHECK_WORDS();
-
- if (argc != 1) {
- LOGE("Command %s requires exactly one argument\n", name);
- return 1;
- }
-
- const char *type;
- if (!strcmp(name, "write_radio_image")) {
- type = "radio";
- } else if (!strcmp(name, "write_hboot_image")) {
- type = "hboot";
- } else {
- LOGE("Unknown firmware update command %s\n", name);
- return 1;
- }
-
- if (!is_package_root_path(argv[0])) {
- LOGE("Command %s: non-package image file \"%s\" not supported\n",
- name, argv[0]);
- return 1;
- }
-
- ui_print("Extracting %s image...\n", type);
- char path[PATH_MAX];
- const ZipArchive *package;
- if (!translate_package_root_path(argv[0], path, sizeof(path), &package)) {
- LOGE("Command %s: bad source path \"%s\"\n", name, argv[0]);
- return 1;
- }
-
- const ZipEntry *entry = mzFindZipEntry(package, path);
- if (entry == NULL) {
- LOGE("Can't find %s\n", path);
- return 1;
- }
-
- // Load the update image into RAM.
- struct FirmwareContext context;
- context.total_bytes = mzGetZipEntryUncompLen(entry);
- context.done_bytes = 0;
- context.data = malloc(context.total_bytes);
- if (context.data == NULL) {
- LOGE("Can't allocate %d bytes for %s\n", context.total_bytes, argv[0]);
- return 1;
- }
-
- if (!mzProcessZipEntryContents(package, entry, firmware_fn, &context) ||
- context.done_bytes != context.total_bytes) {
- LOGE("Can't read %s\n", argv[0]);
- free(context.data);
- return 1;
- }
-
- if (remember_firmware_update(type, context.data, context.total_bytes)) {
- LOGE("Can't store %s image\n", type);
- free(context.data);
- return 1;
- }
-
- return 0;
-}
-
-static bool write_raw_image_process_fn(
- const unsigned char *data,
- int data_len, void *ctx)
-{
- int r = mtd_write_data((MtdWriteContext*)ctx, (const char *)data, data_len);
- if (r == data_len) return true;
- LOGE("%s\n", strerror(errno));
- return false;
-}
-
-/* write_raw_image <src-image> <dest-root>
- */
-static int
-cmd_write_raw_image(const char *name, void *cookie,
- int argc, const char *argv[])
-{
- UNUSED(cookie);
- CHECK_WORDS();
-
- if (argc != 2) {
- LOGE("Command %s requires exactly two arguments\n", name);
- return 1;
- }
-
- // Use 10% of the progress bar (20% post-verification) by default
- const char *src_root_path = argv[0];
- const char *dst_root_path = argv[1];
- ui_print("Writing %s...\n", dst_root_path);
- if (!gDidShowProgress) ui_show_progress(DEFAULT_IMAGE_PROGRESS_FRACTION, 0);
-
- /* Find the source image, which is probably in a package.
- */
- if (!is_package_root_path(src_root_path)) {
- LOGE("Command %s: non-package source path \"%s\" not yet supported\n",
- name, src_root_path);
- return 255;
- }
-
- /* Get the package.
- */
- char srcpathbuf[PATH_MAX];
- const char *src_path;
- const ZipArchive *package;
- src_path = translate_package_root_path(src_root_path,
- srcpathbuf, sizeof(srcpathbuf), &package);
- if (src_path == NULL) {
- LOGE("Command %s: bad source path \"%s\"\n", name, src_root_path);
- return 1;
- }
-
- /* Get the entry.
- */
- const ZipEntry *entry = mzFindZipEntry(package, src_path);
- if (entry == NULL) {
- LOGE("Missing file %s\n", src_path);
- return 1;
- }
-
- /* Unmount the destination root if it isn't already.
- */
- int ret = ensure_root_path_unmounted(dst_root_path);
- if (ret < 0) {
- LOGE("Can't unmount %s\n", dst_root_path);
- return 1;
- }
-
- /* Open the partition for writing.
- */
- const MtdPartition *partition = get_root_mtd_partition(dst_root_path);
- if (partition == NULL) {
- LOGE("Can't find %s\n", dst_root_path);
- return 1;
- }
- MtdWriteContext *context = mtd_write_partition(partition);
- if (context == NULL) {
- LOGE("Can't open %s\n", dst_root_path);
- return 1;
- }
-
- /* Extract and write the image.
- */
- bool ok = mzProcessZipEntryContents(package, entry,
- write_raw_image_process_fn, context);
- if (!ok) {
- LOGE("Error writing %s\n", dst_root_path);
- mtd_write_close(context);
- return 1;
- }
-
- if (mtd_erase_blocks(context, -1) == (off_t) -1) {
- LOGE("Error finishing %s\n", dst_root_path);
- mtd_write_close(context);
- return -1;
- }
-
- if (mtd_write_close(context)) {
- LOGE("Error closing %s\n", dst_root_path);
- return -1;
- }
- return 0;
-}
-
-/* mark <resource> dirty|clean
- */
-static int
-cmd_mark(const char *name, void *cookie, int argc, const char *argv[])
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_WORDS();
-//xxx when marking, save the top-level hash at the mark point
-// so we can retry on failure. Otherwise the hashes won't match,
-// or someone could intentionally dirty the FS to force a downgrade
-//xxx
- return -1;
-}
-
-/* done
- */
-static int
-cmd_done(const char *name, void *cookie, int argc, const char *argv[])
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_WORDS();
-//xxx
- return -1;
-}
-
-
-/*
- * Function definitions
- */
-
-/* compatible_with(<version>)
- *
- * Returns "true" if this version of the script parser and command
- * set supports the named version.
- */
-static int
-fn_compatible_with(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_FN();
-
- if (argc != 1) {
- fprintf(stderr, "%s: wrong number of arguments (%d)\n",
- name, argc);
- return 1;
- }
-
- if (!strcmp(argv[0], "0.1") || !strcmp(argv[0], "0.2")) {
- *result = strdup("true");
- } else {
- *result = strdup("");
- }
- if (resultLen != NULL) {
- *resultLen = strlen(*result);
- }
- return 0;
-}
-
-/* update_forced()
- *
- * Returns "true" if some system setting has determined that
- * the update should happen no matter what.
- */
-static int
-fn_update_forced(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_FN();
-
- if (argc != 0) {
- fprintf(stderr, "%s: wrong number of arguments (%d)\n",
- name, argc);
- return 1;
- }
-
- //xxx check some global or property
- bool force = true;
- if (force) {
- *result = strdup("true");
- } else {
- *result = strdup("");
- }
- if (resultLen != NULL) {
- *resultLen = strlen(*result);
- }
-
- return 0;
-}
-
-/* get_mark(<resource>)
- *
- * Returns the current mark associated with the provided resource.
- */
-static int
-fn_get_mark(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_FN();
-
- if (argc != 1) {
- fprintf(stderr, "%s: wrong number of arguments (%d)\n",
- name, argc);
- return 1;
- }
-
- //xxx look up the value
- *result = strdup("");
- if (resultLen != NULL) {
- *resultLen = strlen(*result);
- }
-
- return 0;
-}
-
-/* hash_dir(<path-to-directory>)
- */
-static int
-fn_hash_dir(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- int ret = -1;
-
- UNUSED(name);
- UNUSED(cookie);
- CHECK_FN();
-
- const char *dir;
- if (argc != 1) {
- fprintf(stderr, "%s: wrong number of arguments (%d)\n",
- name, argc);
- return 1;
- } else {
- dir = argv[0];
- }
-
- return ret;
-}
-
-/* matches(<str>, <str1> [, <strN>...])
- * If <str> matches (strcmp) any of <str1>...<strN>, returns <str>,
- * otherwise returns "".
- *
- * E.g., assert matches(hash_dir("/path"), "hash1", "hash2")
- */
-static int
-fn_matches(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_FN();
-
- if (argc < 2) {
- fprintf(stderr, "%s: not enough arguments (%d < 2)\n",
- name, argc);
- return 1;
- }
-
- int i;
- for (i = 1; i < argc; i++) {
- if (strcmp(argv[0], argv[i]) == 0) {
- *result = strdup(argv[0]);
- if (resultLen != NULL) {
- *resultLen = strlen(*result);
- }
- return 0;
- }
- }
-
- *result = strdup("");
- if (resultLen != NULL) {
- *resultLen = 1;
- }
- return 0;
-}
-
-/* concat(<str>, <str1> [, <strN>...])
- * Returns the concatenation of all strings.
- */
-static int
-fn_concat(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- UNUSED(name);
- UNUSED(cookie);
- CHECK_FN();
-
- size_t totalLen = 0;
- int i;
- for (i = 0; i < argc; i++) {
- totalLen += strlen(argv[i]);
- }
-
- char *s = (char *)malloc(totalLen + 1);
- if (s == NULL) {
- return -1;
- }
- s[totalLen] = '\0';
- for (i = 0; i < argc; i++) {
- //TODO: keep track of the end to avoid walking the string each time
- strcat(s, argv[i]);
- }
- *result = s;
- if (resultLen != NULL) {
- *resultLen = strlen(s);
- }
-
- return 0;
-}
-
-/* getprop(<property>)
- * Returns the named Android system property value, or "" if not set.
- */
-static int
-fn_getprop(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- UNUSED(cookie);
- CHECK_FN();
-
- if (argc != 1) {
- LOGE("Command %s requires exactly one argument\n", name);
- return 1;
- }
-
- char value[PROPERTY_VALUE_MAX];
- property_get(argv[0], value, "");
-
- *result = strdup(value);
- if (resultLen != NULL) {
- *resultLen = strlen(*result);
- }
-
- return 0;
-}
-
-/* file_contains(<filename>, <substring>)
- * Returns "true" if the file exists and contains the specified substring.
- */
-static int
-fn_file_contains(const char *name, void *cookie, int argc, const char *argv[],
- char **result, size_t *resultLen)
-{
- UNUSED(cookie);
- CHECK_FN();
-
- if (argc != 2) {
- LOGE("Command %s requires exactly two arguments\n", name);
- return 1;
- }
-
- char pathbuf[PATH_MAX];
- const char *root_path = argv[0];
- const char *path = translate_root_path(root_path, pathbuf, sizeof(pathbuf));
- if (path == NULL) {
- LOGE("Command %s: bad path \"%s\"\n", name, root_path);
- return 1;
- }
-
- if (ensure_root_path_mounted(root_path)) {
- LOGE("Can't mount %s\n", root_path);
- return 1;
- }
-
- const char *needle = argv[1];
- char *haystack = (char*) load_file(path, NULL);
- if (haystack == NULL) {
- LOGI("%s: Can't read \"%s\" (%s)\n", name, path, strerror(errno));
- *result = ""; /* File not found is not an error. */
- } else if (strstr(haystack, needle) == NULL) {
- LOGI("%s: Can't find \"%s\" in \"%s\"\n", name, needle, path);
- *result = strdup("");
- free(haystack);
- } else {
- *result = strdup("true");
- free(haystack);
- }
-
- if (resultLen != NULL) {
- *resultLen = strlen(*result);
- }
- return 0;
-}
-
-int
-register_update_commands(RecoveryCommandContext *ctx)
-{
- int ret;
-
- ret = commandInit();
- if (ret < 0) return ret;
-
- /*
- * Commands
- */
-
- ret = registerCommand("assert", CMD_ARGS_BOOLEAN, cmd_assert, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("delete", CMD_ARGS_WORDS, cmd_delete, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("delete_recursive", CMD_ARGS_WORDS, cmd_delete,
- (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("copy_dir", CMD_ARGS_WORDS,
- cmd_copy_dir, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("run_program", CMD_ARGS_WORDS,
- cmd_run_program, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("set_perm", CMD_ARGS_WORDS,
- cmd_set_perm, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("set_perm_recursive", CMD_ARGS_WORDS,
- cmd_set_perm, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("show_progress", CMD_ARGS_WORDS,
- cmd_show_progress, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("symlink", CMD_ARGS_WORDS, cmd_symlink, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("format", CMD_ARGS_WORDS, cmd_format, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("write_radio_image", CMD_ARGS_WORDS,
- cmd_write_firmware_image, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("write_hboot_image", CMD_ARGS_WORDS,
- cmd_write_firmware_image, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("write_raw_image", CMD_ARGS_WORDS,
- cmd_write_raw_image, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("mark", CMD_ARGS_WORDS, cmd_mark, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerCommand("done", CMD_ARGS_WORDS, cmd_done, (void *)ctx);
- if (ret < 0) return ret;
-
- /*
- * Functions
- */
-
- ret = registerFunction("compatible_with", fn_compatible_with, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerFunction("update_forced", fn_update_forced, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerFunction("get_mark", fn_get_mark, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerFunction("hash_dir", fn_hash_dir, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerFunction("matches", fn_matches, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerFunction("concat", fn_concat, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerFunction("getprop", fn_getprop, (void *)ctx);
- if (ret < 0) return ret;
-
- ret = registerFunction("file_contains", fn_file_contains, (void *)ctx);
- if (ret < 0) return ret;
-
- return 0;
-}
diff --git a/commands.h b/commands.h
deleted file mode 100644
index e9acea2..0000000
--- a/commands.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * 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 RECOVERY_COMMANDS_H_
-#define RECOVERY_COMMANDS_H_
-
-#include "minzip/Zip.h"
-
-typedef struct {
- ZipArchive *package;
-} RecoveryCommandContext;
-
-int register_update_commands(RecoveryCommandContext *ctx);
-
-#endif // RECOVERY_COMMANDS_H_
diff --git a/default_recovery_ui.c b/default_recovery_ui.c
new file mode 100644
index 0000000..d4e6204
--- /dev/null
+++ b/default_recovery_ui.c
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * 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 <linux/input.h>
+
+#include "recovery_ui.h"
+#include "common.h"
+
+char* MENU_HEADERS[] = { "Android system recovery utility",
+ "",
+ NULL };
+
+char* MENU_ITEMS[] = { "reboot system now",
+ "apply sdcard:update.zip",
+ "wipe data/factory reset",
+ "wipe cache partition",
+ NULL };
+
+int device_toggle_display(volatile char* key_pressed, int key_code) {
+ return key_code == KEY_HOME;
+}
+
+int device_reboot_now(volatile char* key_pressed, int key_code) {
+ return 0;
+}
+
+int device_handle_key(int key_code, int visible) {
+ if (visible) {
+ switch (key_code) {
+ case KEY_DOWN:
+ case KEY_VOLUMEDOWN:
+ return HIGHLIGHT_DOWN;
+
+ case KEY_UP:
+ case KEY_VOLUMEUP:
+ return HIGHLIGHT_UP;
+
+ case KEY_ENTER:
+ return SELECT_ITEM;
+ }
+ }
+
+ return NO_ACTION;
+}
+
+int device_perform_action(int which) {
+ return which;
+}
+
+int device_wipe_data() {
+ return 0;
+}
diff --git a/install.c b/install.c
index ab19478..2c557ea 100644
--- a/install.c
+++ b/install.c
@@ -22,7 +22,6 @@
#include <sys/wait.h>
#include <unistd.h>
-#include "amend/amend.h"
#include "common.h"
#include "install.h"
#include "mincrypt/rsa.h"
@@ -35,85 +34,9 @@
#include "verifier.h"
#include "firmware.h"
-#define ASSUMED_UPDATE_SCRIPT_NAME "META-INF/com/google/android/update-script"
#define ASSUMED_UPDATE_BINARY_NAME "META-INF/com/google/android/update-binary"
#define PUBLIC_KEYS_FILE "/res/keys"
-static const ZipEntry *
-find_update_script(ZipArchive *zip)
-{
-//TODO: Get the location of this script from the MANIFEST.MF file
- return mzFindZipEntry(zip, ASSUMED_UPDATE_SCRIPT_NAME);
-}
-
-static int read_data(ZipArchive *zip, const ZipEntry *entry,
- char** ppData, int* pLength) {
- int len = (int)mzGetZipEntryUncompLen(entry);
- if (len <= 0) {
- LOGE("Bad data length %d\n", len);
- return -1;
- }
- char *data = malloc(len + 1);
- if (data == NULL) {
- LOGE("Can't allocate %d bytes for data\n", len + 1);
- return -2;
- }
- bool ok = mzReadZipEntry(zip, entry, data, len);
- if (!ok) {
- LOGE("Error while reading data\n");
- free(data);
- return -3;
- }
- data[len] = '\0'; // not necessary, but just to be safe
- *ppData = data;
- if (pLength) {
- *pLength = len;
- }
- return 0;
-}
-
-static int
-handle_update_script(ZipArchive *zip, const ZipEntry *update_script_entry)
-{
- /* Read the entire script into a buffer.
- */
- int script_len;
- char* script_data;
- if (read_data(zip, update_script_entry, &script_data, &script_len) < 0) {
- LOGE("Can't read update script\n");
- return INSTALL_ERROR;
- }
-
- /* Parse the script. Note that the script and parse tree are never freed.
- */
- const AmCommandList *commands = parseAmendScript(script_data, script_len);
- if (commands == NULL) {
- LOGE("Syntax error in update script\n");
- return INSTALL_ERROR;
- } else {
- UnterminatedString name = mzGetZipEntryFileName(update_script_entry);
- LOGI("Parsed %.*s\n", name.len, name.str);
- }
-
- /* Execute the script.
- */
- int ret = execCommandList((ExecContext *)1, commands);
- if (ret != 0) {
- int num = ret;
- char *line = NULL, *next = script_data;
- while (next != NULL && ret-- > 0) {
- line = next;
- next = memchr(line, '\n', script_data + script_len - line);
- if (next != NULL) *next++ = '\0';
- }
- LOGE("Failure at line %d:\n%s\n", num, next ? line : "(not found)");
- return INSTALL_ERROR;
- }
-
- LOGI("Installation complete.\n");
- return INSTALL_SUCCESS;
-}
-
// The update binary ask us to install a firmware file on reboot. Set
// that up. Takes ownership of type and filename.
static int
@@ -252,11 +175,9 @@
char* firmware_type = NULL;
char* firmware_filename = NULL;
- char buffer[81];
+ char buffer[1024];
FILE* from_child = fdopen(pipefd[0], "r");
while (fgets(buffer, sizeof(buffer), from_child) != NULL) {
- LOGI("read: %s", buffer);
-
char* command = strtok(buffer, " \n");
if (command == NULL) {
continue;
@@ -331,30 +252,8 @@
ui_print("Installing update...\n");
int result = try_update_binary(path, zip);
- if (result == INSTALL_SUCCESS || result == INSTALL_ERROR) {
- register_package_root(NULL, NULL); // Unregister package root
- return result;
- }
-
- // if INSTALL_CORRUPT is returned, this package doesn't have an
- // update binary. Fall back to the older mechanism of looking for
- // an update script.
-
- const ZipEntry *script_entry;
- script_entry = find_update_script(zip);
- if (script_entry == NULL) {
- LOGE("Can't find update script\n");
- return INSTALL_CORRUPT;
- }
-
- if (register_package_root(zip, path) < 0) {
- LOGE("Can't register package root\n");
- return INSTALL_ERROR;
- }
-
- int ret = handle_update_script(zip, script_entry);
register_package_root(NULL, NULL); // Unregister package root
- return ret;
+ return result;
}
// Reads a file containing one or more public keys as produced by
diff --git a/minui/graphics.c b/minui/graphics.c
index 06c5fdf..adbfc09 100644
--- a/minui/graphics.c
+++ b/minui/graphics.c
@@ -115,6 +115,7 @@
if (n > 1) return;
vi.yres_virtual = vi.yres * 2;
vi.yoffset = n * vi.yres;
+ vi.bits_per_pixel = 16;
if (ioctl(gr_fb_fd, FBIOPUT_VSCREENINFO, &vi) < 0) {
perror("active fb swap failed");
}
diff --git a/minui/minui.h b/minui/minui.h
index 80b47a4..567d421 100644
--- a/minui/minui.h
+++ b/minui/minui.h
@@ -41,22 +41,6 @@
// see http://www.mjmwired.net/kernel/Documentation/input/ for info.
struct input_event;
-// Dream-specific key codes
-#define KEY_DREAM_HOME 102 // = KEY_HOME
-#define KEY_DREAM_RED 107 // = KEY_END
-#define KEY_DREAM_VOLUMEDOWN 114 // = KEY_VOLUMEDOWN
-#define KEY_DREAM_VOLUMEUP 115 // = KEY_VOLUMEUP
-#define KEY_DREAM_SYM 127 // = KEY_COMPOSE
-#define KEY_DREAM_MENU 139 // = KEY_MENU
-#define KEY_DREAM_BACK 158 // = KEY_BACK
-#define KEY_DREAM_FOCUS 211 // = KEY_HP (light touch on camera)
-#define KEY_DREAM_CAMERA 212 // = KEY_CAMERA
-#define KEY_DREAM_AT 215 // = KEY_EMAIL
-#define KEY_DREAM_GREEN 231
-#define KEY_DREAM_FATTOUCH 258 // = BTN_2 ???
-#define KEY_DREAM_BALL 272 // = BTN_MOUSE
-#define KEY_DREAM_TOUCH 330 // = BTN_TOUCH
-
int ev_init(void);
void ev_exit(void);
int ev_get(struct input_event *ev, unsigned dont_wait);
diff --git a/recovery.c b/recovery.c
index 5ccd38f..ed6a9c8 100644
--- a/recovery.c
+++ b/recovery.c
@@ -29,7 +29,6 @@
#include <unistd.h>
#include "bootloader.h"
-#include "commands.h"
#include "common.h"
#include "cutils/properties.h"
#include "firmware.h"
@@ -37,6 +36,7 @@
#include "minui/minui.h"
#include "minzip/DirUtil.h"
#include "roots.h"
+#include "recovery_ui.h"
static const struct option OPTIONS[] = {
{ "send_intent", required_argument, NULL, 's' },
@@ -258,23 +258,6 @@
sync(); // For good measure.
}
-#define TEST_AMEND 0
-#if TEST_AMEND
-static void
-test_amend()
-{
- extern int test_symtab(void);
- extern int test_cmd_fn(void);
- int ret;
- LOGD("Testing symtab...\n");
- ret = test_symtab();
- LOGD(" returned %d\n", ret);
- LOGD("Testing cmd_fn...\n");
- ret = test_cmd_fn();
- LOGD(" returned %d\n", ret);
-}
-#endif // TEST_AMEND
-
static int
erase_root(const char *root)
{
@@ -287,26 +270,25 @@
static void
prompt_and_wait()
{
- char* headers[] = { "Android system recovery <"
- EXPAND(RECOVERY_API_VERSION) ">",
- "",
- "Use trackball to highlight;",
- "click to select.",
- "",
- NULL };
-
- // these constants correspond to elements of the items[] list.
-#define ITEM_REBOOT 0
-#define ITEM_APPLY_SDCARD 1
-#define ITEM_WIPE_DATA 2
-#define ITEM_WIPE_CACHE 3
- char* items[] = { "reboot system now [Home+Back]",
- "apply sdcard:update.zip [Alt+S]",
- "wipe data/factory reset [Alt+W]",
- "wipe cache partition",
+ char* title[] = { "Android system recovery <"
+ EXPAND(RECOVERY_API_VERSION) "e>",
+ "",
NULL };
- ui_start_menu(headers, items);
+ // count the number of lines in our title, plus the
+ // product-provided headers.
+ int count = 0;
+ char** p;
+ for (p = title; *p; ++p, ++count);
+ for (p = MENU_HEADERS; *p; ++p, ++count);
+
+ char** headers = malloc((count+1) * sizeof(char*));
+ char** h = headers;
+ for (p = title; *p; ++p, ++h) *h = *p;
+ for (p = MENU_HEADERS; *p; ++p, ++h) *h = *p;
+ *h = NULL;
+
+ ui_start_menu(headers, MENU_ITEMS);
int selected = 0;
int chosen_item = -1;
@@ -314,29 +296,28 @@
ui_reset_progress();
for (;;) {
int key = ui_wait_key();
- int alt = ui_key_pressed(KEY_LEFTALT) || ui_key_pressed(KEY_RIGHTALT);
int visible = ui_text_visible();
- if (key == KEY_DREAM_BACK && ui_key_pressed(KEY_DREAM_HOME)) {
- // Wait for the keys to be released, to avoid triggering
- // special boot modes (like coming back into recovery!).
- while (ui_key_pressed(KEY_DREAM_BACK) ||
- ui_key_pressed(KEY_DREAM_HOME)) {
- usleep(1000);
+ int action = device_handle_key(key, visible);
+
+ if (action < 0) {
+ switch (action) {
+ case HIGHLIGHT_UP:
+ --selected;
+ selected = ui_menu_select(selected);
+ break;
+ case HIGHLIGHT_DOWN:
+ ++selected;
+ selected = ui_menu_select(selected);
+ break;
+ case SELECT_ITEM:
+ chosen_item = selected;
+ break;
+ case NO_ACTION:
+ break;
}
- chosen_item = ITEM_REBOOT;
- } else if (alt && key == KEY_W) {
- chosen_item = ITEM_WIPE_DATA;
- } else if (alt && key == KEY_S) {
- chosen_item = ITEM_APPLY_SDCARD;
- } else if ((key == KEY_DOWN || key == KEY_VOLUMEDOWN) && visible) {
- ++selected;
- selected = ui_menu_select(selected);
- } else if ((key == KEY_UP || key == KEY_VOLUMEUP) && visible) {
- --selected;
- selected = ui_menu_select(selected);
- } else if (key == BTN_MOUSE && visible) {
- chosen_item = selected;
+ } else {
+ chosen_item = action;
}
if (chosen_item >= 0) {
@@ -344,12 +325,18 @@
// on the screen.
ui_end_menu();
+ // device-specific code may take some action here. It may
+ // return one of the core actions handled in the switch
+ // statement below.
+ chosen_item = device_perform_action(chosen_item);
+
switch (chosen_item) {
case ITEM_REBOOT:
return;
case ITEM_WIPE_DATA:
ui_print("\n-- Wiping data...\n");
+ device_wipe_data();
erase_root("DATA:");
erase_root("CACHE:");
ui_print("Data wipe complete.\n");
@@ -373,8 +360,8 @@
return; // reboot if logs aren't visible
} else {
if (firmware_update_pending()) {
- ui_print("\nReboot via home+back or menu\n"
- "to complete installation.\n");
+ ui_print("\nReboot via menu to complete\n"
+ "installation.\n");
} else {
ui_print("\nInstall from sdcard complete.\n");
}
@@ -384,7 +371,7 @@
// if we didn't return from this function to reboot, show
// the menu again.
- ui_start_menu(headers, items);
+ ui_start_menu(headers, MENU_ITEMS);
selected = 0;
chosen_item = -1;
@@ -445,24 +432,19 @@
property_list(print_property, NULL);
fprintf(stderr, "\n");
-#if TEST_AMEND
- test_amend();
-#endif
-
- RecoveryCommandContext ctx = { NULL };
- if (register_update_commands(&ctx)) {
- LOGE("Can't install update commands\n");
- }
-
int status = INSTALL_SUCCESS;
if (update_package != NULL) {
status = install_package(update_package);
if (status != INSTALL_SUCCESS) ui_print("Installation aborted.\n");
- } else if (wipe_data || wipe_cache) {
- if (wipe_data && erase_root("DATA:")) status = INSTALL_ERROR;
+ } else if (wipe_data) {
+ if (device_wipe_data()) status = INSTALL_ERROR;
+ if (erase_root("DATA:")) status = INSTALL_ERROR;
if (wipe_cache && erase_root("CACHE:")) status = INSTALL_ERROR;
if (status != INSTALL_SUCCESS) ui_print("Data wipe failed.\n");
+ } else if (wipe_cache) {
+ if (wipe_cache && erase_root("CACHE:")) status = INSTALL_ERROR;
+ if (status != INSTALL_SUCCESS) ui_print("Cache wipe failed.\n");
} else {
status = INSTALL_ERROR; // No command specified
}
diff --git a/recovery_ui.h b/recovery_ui.h
new file mode 100644
index 0000000..8818ef3
--- /dev/null
+++ b/recovery_ui.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * 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 _RECOVERY_UI_H
+#define _RECOVERY_UI_H
+
+// Called in the input thread when a new key (key_code) is pressed.
+// *key_pressed is an array of KEY_MAX+1 bytes indicating which other
+// keys are already pressed. Return true if the text display should
+// be toggled.
+extern int device_toggle_display(volatile char* key_pressed, int key_code);
+
+// Called in the input thread when a new key (key_code) is pressed.
+// *key_pressed is an array of KEY_MAX+1 bytes indicating which other
+// keys are already pressed. Return true if the device should reboot
+// immediately.
+extern int device_reboot_now(volatile char* key_pressed, int key_code);
+
+// Called from the main thread when recovery is waiting for input and
+// a key is pressed. key is the code of the key pressed; visible is
+// true if the recovery menu is being shown. Implementations can call
+// ui_key_pressed() to discover if other keys are being held down.
+// Return one of the defined constants below in order to:
+//
+// - move the menu highlight (HIGHLIGHT_*)
+// - invoke the highlighted item (SELECT_ITEM)
+// - do nothing (NO_ACTION)
+// - invoke a specific action (a menu position: any non-negative number)
+extern int device_handle_key(int key, int visible);
+
+// Perform a recovery action selected from the menu. 'which' will be
+// the item number of the selected menu item, or a non-negative number
+// returned from device_handle_key(). The menu will be hidden when
+// this is called; implementations can call ui_print() to print
+// information to the screen.
+extern int device_perform_action(int which);
+
+// Called when we do a wipe data/factory reset operation (either via a
+// reboot from the main system with the --wipe_data flag, or when the
+// user boots into recovery manually and selects the option from the
+// menu.) Can perform whatever device-specific wiping actions are
+// needed. Return 0 on success. The userdata and cache partitions
+// are erased after this returns (whether it returns success or not).
+int device_wipe_data();
+
+#define NO_ACTION -1
+
+#define HIGHLIGHT_UP -2
+#define HIGHLIGHT_DOWN -3
+#define SELECT_ITEM -4
+
+#define ITEM_REBOOT 0
+#define ITEM_APPLY_SDCARD 1
+#define ITEM_WIPE_DATA 2
+#define ITEM_WIPE_CACHE 3
+
+// Header text to display above the main menu.
+extern char* MENU_HEADERS[];
+
+// Text of menu items.
+extern char* MENU_ITEMS[];
+
+#endif
diff --git a/res/images/icon_error.png b/res/images/icon_error.png
index 7064c2e..6cb71c0 100644
--- a/res/images/icon_error.png
+++ b/res/images/icon_error.png
Binary files differ
diff --git a/res/images/icon_firmware_install.png b/res/images/icon_firmware_install.png
index ee2afac..8bfe775 100644
--- a/res/images/icon_firmware_install.png
+++ b/res/images/icon_firmware_install.png
Binary files differ
diff --git a/res/images/icon_installing.png b/res/images/icon_installing.png
index f24f2e3..1aeb9d9 100644
--- a/res/images/icon_installing.png
+++ b/res/images/icon_installing.png
Binary files differ
diff --git a/roots.c b/roots.c
index 6a6cf8a..8f8dace 100644
--- a/roots.c
+++ b/roots.c
@@ -52,6 +52,7 @@
{ "RECOVERY:", g_mtd_device, NULL, "recovery", "/", g_raw },
{ "SDCARD:", "/dev/block/mmcblk0p1", "/dev/block/mmcblk0", NULL, "/sdcard", "vfat" },
{ "SYSTEM:", g_mtd_device, NULL, "system", "/system", "yaffs2" },
+ { "MBM:", g_mtd_device, NULL, "mbm", NULL, g_raw },
{ "TMP:", NULL, NULL, NULL, "/tmp", NULL },
};
#define NUM_ROOTS (sizeof(g_roots) / sizeof(g_roots[0]))
diff --git a/tools/ota/Android.mk b/tools/ota/Android.mk
index b7a57d6..0bde7ee 100644
--- a/tools/ota/Android.mk
+++ b/tools/ota/Android.mk
@@ -14,11 +14,6 @@
LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-LOCAL_MODULE := make-update-script
-LOCAL_SRC_FILES := make-update-script.c
-include $(BUILD_HOST_EXECUTABLE)
-
ifneq ($(TARGET_SIMULATOR),true)
include $(CLEAR_VARS)
diff --git a/tools/ota/make-update-script.c b/tools/ota/make-update-script.c
deleted file mode 100644
index 1e1148b..0000000
--- a/tools/ota/make-update-script.c
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * 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 "private/android_filesystem_config.h"
-
-#include <dirent.h>
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-/*
- * Recursively walk the directory tree at <sysdir>/<subdir>, writing
- * script commands to set permissions and create symlinks.
- * Assume the contents already have the specified default permissions,
- * so only output commands if they need to be changed from the defaults.
- *
- * Note that permissions are set by fs_config(), which uses a lookup table of
- * Android permissions. They are not drawn from the build host filesystem.
- */
-static void walk_files(
- const char *sysdir, const char *subdir,
- unsigned default_uid, unsigned default_gid,
- unsigned default_dir_mode, unsigned default_file_mode) {
- const char *sep = strcmp(subdir, "") ? "/" : "";
-
- char fn[PATH_MAX];
- unsigned dir_uid = 0, dir_gid = 0, dir_mode = 0;
- snprintf(fn, PATH_MAX, "system%s%s", sep, subdir);
- fs_config(fn, 1, &dir_uid, &dir_gid, &dir_mode);
-
- snprintf(fn, PATH_MAX, "%s%s%s", sysdir, sep, subdir);
- DIR *dir = opendir(fn);
- if (dir == NULL) {
- perror(fn);
- exit(1);
- }
-
- /*
- * We can use "set_perm" and "set_perm_recursive" to set file permissions
- * (owner, group, and file mode) for individual files and entire subtrees.
- * We want to use set_perm_recursive efficiently to avoid setting the
- * permissions of every single file in the system image individually.
- *
- * What we do is recursively set our entire subtree to the permissions
- * used by the first file we encounter, and then use "set_perm" to adjust
- * the permissions of subsequent files which don't match the first one.
- * This is bad if the first file is an outlier, but it generally works.
- * Subdirectories can do the same thing recursively if they're different.
- */
-
- int is_first = 1;
- const struct dirent *e;
- while ((e = readdir(dir))) {
- // Skip over "." and ".." entries
- if (!strcmp(e->d_name, ".") || !strcmp(e->d_name, "..")) continue;
-
- if (e->d_type == DT_LNK) { // Symlink
-
- // Symlinks don't really have permissions, so this is orthogonal.
- snprintf(fn, PATH_MAX, "%s/%s%s%s", sysdir, subdir, sep, e->d_name);
- int len = readlink(fn, fn, PATH_MAX - 1);
- if (len <= 0) {
- perror(fn);
- exit(1);
- }
- fn[len] = '\0';
- printf("symlink %s SYSTEM:%s%s%s\n", fn, subdir, sep, e->d_name);
-
- } else if (e->d_type == DT_DIR) { // Subdirectory
-
- // Use the parent directory as the model for default permissions.
- // We haven't seen a file, so just make up some file defaults.
- if (is_first && (
- dir_mode != default_dir_mode ||
- dir_uid != default_uid || dir_gid != default_gid)) {
- default_uid = dir_uid;
- default_gid = dir_gid;
- default_dir_mode = dir_mode;
- default_file_mode = dir_mode & default_file_mode & 0666;
- printf("set_perm_recursive %d %d 0%o 0%o SYSTEM:%s\n",
- default_uid, default_gid,
- default_dir_mode, default_file_mode,
- subdir);
- }
-
- is_first = 0;
-
- // Recursively handle the subdirectory.
- // Note, the recursive call handles the directory's own permissions.
- snprintf(fn, PATH_MAX, "%s%s%s", subdir, sep, e->d_name);
- walk_files(sysdir, fn,
- default_uid, default_gid,
- default_dir_mode, default_file_mode);
-
- } else { // Ordinary file
-
- // Get the file's desired permissions.
- unsigned file_uid = 0, file_gid = 0, file_mode = 0;
- snprintf(fn, PATH_MAX, "system/%s%s%s", subdir, sep, e->d_name);
- fs_config(fn, 0, &file_uid, &file_gid, &file_mode);
-
- // If this is the first file, its mode gets to become the default.
- if (is_first && (
- dir_mode != default_dir_mode ||
- file_mode != default_file_mode ||
- dir_uid != default_uid || file_uid != default_uid ||
- dir_gid != default_gid || file_gid != default_gid)) {
- default_uid = dir_uid;
- default_gid = dir_gid;
- default_dir_mode = dir_mode;
- default_file_mode = file_mode;
- printf("set_perm_recursive %d %d 0%o 0%o SYSTEM:%s\n",
- default_uid, default_gid,
- default_dir_mode, default_file_mode,
- subdir);
- }
-
- is_first = 0;
-
- // Otherwise, override this file if it doesn't match the defaults.
- if (file_mode != default_file_mode ||
- file_uid != default_uid || file_gid != default_gid) {
- printf("set_perm %d %d 0%o SYSTEM:%s%s%s\n",
- file_uid, file_gid, file_mode,
- subdir, sep, e->d_name);
- }
-
- }
- }
-
- // Set the directory's permissions directly, if they never got set.
- if (dir_mode != default_dir_mode ||
- dir_uid != default_uid || dir_gid != default_gid) {
- printf("set_perm %d %d 0%o SYSTEM:%s\n",
- dir_uid, dir_gid, dir_mode, subdir);
- }
-
- closedir(dir);
-}
-
-/*
- * Generate the update script (in "Amend", see commands/recovery/commands.c)
- * for the complete-reinstall OTA update packages the build system makes.
- *
- * The generated script makes a variety of sanity checks about the device,
- * erases and reinstalls system files, and sets file permissions appropriately.
- */
-int main(int argc, char *argv[]) {
- if (argc != 3) {
- fprintf(stderr, "usage: %s systemdir android-info.txt >update-script\n",
- argv[0]);
- return 2;
- }
-
- // ensure basic recovery script language compatibility
- printf("assert compatible_with(\"0.2\") == \"true\"\n");
-
- // if known, make sure the device name is correct
- const char *device = getenv("TARGET_DEVICE");
- if (device != NULL) {
- printf("assert getprop(\"ro.product.device\") == \"%s\" || "
- "getprop(\"ro.build.product\") == \"%s\"\n", device, device);
- }
-
- // scan android-info.txt to enforce compatibility with the target system
- FILE *fp = fopen(argv[2], "r");
- if (fp == NULL) {
- perror(argv[2]);
- return 1;
- }
-
- // The lines we're looking for look like:
- // version-bootloader=x.yy.zzzz|x.yy.zzzz|...
- // or:
- // require version-bootloader=x.yy.zzzz|x.yy.zzzz|...
- char line[256];
- while (fgets(line, sizeof(line), fp)) {
- const char *name = strtok(line, "="), *value = strtok(NULL, "|\n");
- if (value != NULL &&
- (!strcmp(name, "version-bootloader") ||
- !strcmp(name, "require version-bootloader"))) {
- printf("assert getprop(\"ro.bootloader\") == \"%s\"", value);
-
- while ((value = strtok(NULL, "|\n")) != NULL) {
- printf(" || getprop(\"ro.bootloader\") == \"%s\"", value);
- }
- printf("\n");
- }
- // We also used to check version-baseband, but we update radio.img
- // ourselves, so there's no need.
- }
-
- // erase the boot sector first, so if the update gets interrupted,
- // the system will reboot into the recovery partition and start over.
- printf("format BOOT:\n");
-
- // write the radio image (actually just loads it into RAM for now)
- printf("show_progress 0.1 0\n");
- printf("write_radio_image PACKAGE:radio.img\n");
-
- // erase and reinstall the system image
- printf("show_progress 0.5 0\n");
- printf("format SYSTEM:\n");
- printf("copy_dir PACKAGE:system SYSTEM:\n");
-
- // walk the files in the system image, set their permissions, etc.
- // use -1 for default values to force permissions to be set explicitly.
- walk_files(argv[1], "", -1, -1, -1, -1);
-
- // as the last step, write the boot sector.
- printf("show_progress 0.2 0\n");
- printf("write_raw_image PACKAGE:boot.img BOOT:\n");
-
- // after the end of the script, the radio will be written to cache
- // leave some space in the progress bar for this operation
- printf("show_progress 0.2 10\n");
- return 0;
-}
diff --git a/ui.c b/ui.c
index b84f172..0a8b985 100644
--- a/ui.c
+++ b/ui.c
@@ -27,6 +27,7 @@
#include "common.h"
#include "minui/minui.h"
+#include "recovery_ui.h"
#define MAX_COLS 64
#define MAX_ROWS 32
@@ -307,20 +308,14 @@
}
pthread_mutex_unlock(&key_queue_mutex);
- // Alt+L or Home+End: toggle log display
- int alt = key_pressed[KEY_LEFTALT] || key_pressed[KEY_RIGHTALT];
- if ((alt && ev.code == KEY_L && ev.value > 0) ||
- (key_pressed[KEY_HOME] && ev.code == KEY_END && ev.value > 0)) {
+ if (ev.value > 0 && device_toggle_display(key_pressed, ev.code)) {
pthread_mutex_lock(&gUpdateMutex);
show_text = !show_text;
update_screen_locked();
pthread_mutex_unlock(&gUpdateMutex);
}
- // Green+Menu+Red: reboot immediately
- if (ev.code == KEY_DREAM_RED &&
- key_pressed[KEY_DREAM_MENU] &&
- key_pressed[KEY_DREAM_GREEN]) {
+ if (ev.value > 0 && device_reboot_now(key_pressed, ev.code)) {
reboot(RB_AUTOBOOT);
}
}
diff --git a/updater/Android.mk b/updater/Android.mk
index 897b9d7..d4a4e33 100644
--- a/updater/Android.mk
+++ b/updater/Android.mk
@@ -18,11 +18,47 @@
LOCAL_SRC_FILES := $(updater_src_files)
-LOCAL_STATIC_LIBRARIES := libapplypatch libedify libmtdutils libminzip libz
+LOCAL_STATIC_LIBRARIES := $(TARGET_RECOVERY_UPDATER_LIBS) $(TARGET_RECOVERY_UPDATER_EXTRA_LIBS)
+LOCAL_STATIC_LIBRARIES += libapplypatch libedify libmtdutils libminzip libz
LOCAL_STATIC_LIBRARIES += libmincrypt libbz
LOCAL_STATIC_LIBRARIES += libcutils libstdc++ libc
LOCAL_C_INCLUDES += $(LOCAL_PATH)/..
+# Each library in TARGET_RECOVERY_UPDATER_LIBS should have a function
+# named "Register_<libname>()". Here we emit a little C function that
+# gets #included by updater.c. It calls all those registration
+# functions.
+
+# Devices can also add libraries to TARGET_RECOVERY_UPDATER_EXTRA_LIBS.
+# These libs are also linked in with updater, but we don't try to call
+# any sort of registration function for these. Use this variable for
+# any subsidiary static libraries required for your registered
+# extension libs.
+
+inc := $(call intermediates-dir-for,PACKAGING,updater_extensions)/register.inc
+
+# During the first pass of reading the makefiles, we dump the list of
+# extension libs to a temp file, then copy that to the ".list" file if
+# it is different than the existing .list (if any). The register.inc
+# file then uses the .list as a prerequisite, so it is only rebuilt
+# (and updater.o recompiled) when the list of extension libs changes.
+
+junk := $(shell mkdir -p $(dir $(inc));\
+ echo $(TARGET_RECOVERY_UPDATER_LIBS) > $(inc).temp;\
+ diff -q $(inc).temp $(inc).list || cp -f $(inc).temp $(inc).list)
+
+$(inc) : libs := $(TARGET_RECOVERY_UPDATER_LIBS)
+$(inc) : $(inc).list
+ $(hide) mkdir -p $(dir $@)
+ $(hide) echo "" > $@
+ $(hide) $(foreach lib,$(libs),echo "extern void Register_$(lib)(void);" >> $@)
+ $(hide) echo "void RegisterDeviceExtensions() {" >> $@
+ $(hide) $(foreach lib,$(libs),echo " Register_$(lib)();" >> $@)
+ $(hide) echo "}" >> $@
+
+$(call intermediates-dir-for,EXECUTABLES,updater)/updater.o : $(inc)
+LOCAL_C_INCLUDES += $(dir $(inc))
+
LOCAL_MODULE := updater
LOCAL_FORCE_STATIC_EXECUTABLE := true
diff --git a/updater/updater.c b/updater/updater.c
index 31d93ae..1aa277c 100644
--- a/updater/updater.c
+++ b/updater/updater.c
@@ -23,6 +23,11 @@
#include "install.h"
#include "minzip/Zip.h"
+// Generated by the makefile, this function defines the
+// RegisterDeviceExtensions() function, which calls all the
+// registration functions for device-specific extensions.
+#include "register.inc"
+
// Where in the package we expect to find the edify script to execute.
// (Note it's "updateR-script", not the older "update-script".)
#define SCRIPT_NAME "META-INF/com/google/android/updater-script"
@@ -76,6 +81,7 @@
RegisterBuiltins();
RegisterInstallFunctions();
+ RegisterDeviceExtensions();
FinishRegistration();
// Parse the script.