Cleanup ReadArgs & ReadValueArgs usage

ReadArgs will switch to using std::string and std::unique_ptr. Also
cleanup the callers.

Test: mma & component test passed.
Change-Id: I4724406ae6c0c134a27bbd1cdd24ad5d343b2a3b
This commit is contained in:
Tianjie Xu 2016-10-17 18:15:20 -07:00
parent 3f4030e0ef
commit 5fe280ac96
4 changed files with 430 additions and 638 deletions

View file

@ -254,31 +254,25 @@ Value* LessThanIntFn(const char* name, State* state, int argc, Expr* argv[]) {
return nullptr;
}
char* left;
char* right;
if (ReadArgs(state, argv, 2, &left, &right) < 0) return nullptr;
bool result = false;
char* end;
std::vector<std::string> args;
if (!ReadArgs(state, 2, argv, &args)) {
return nullptr;
}
// Parse up to at least long long or 64-bit integers.
int64_t l_int = static_cast<int64_t>(strtoll(left, &end, 10));
if (left[0] == '\0' || *end != '\0') {
goto done;
int64_t l_int;
if (!android::base::ParseInt(args[0].c_str(), &l_int)) {
state->errmsg = "failed to parse int in " + args[0];
return nullptr;
}
int64_t r_int;
r_int = static_cast<int64_t>(strtoll(right, &end, 10));
if (right[0] == '\0' || *end != '\0') {
goto done;
if (!android::base::ParseInt(args[1].c_str(), &r_int)) {
state->errmsg = "failed to parse int in " + args[1];
return nullptr;
}
result = l_int < r_int;
done:
free(left);
free(right);
return StringValue(result ? "t" : "");
return StringValue(l_int < r_int ? "t" : "");
}
Value* GreaterThanIntFn(const char* name, State* state,
@ -372,99 +366,6 @@ bool ReadValueArgs(State* state, int argc, Expr* argv[],
return true;
}
// Evaluate the expressions in argv, giving 'count' char* (the ... is
// zero or more char** to put them in). If any expression evaluates
// to NULL, free the rest and return -1. Return 0 on success.
int ReadArgs(State* state, Expr* argv[], int count, ...) {
char** args = reinterpret_cast<char**>(malloc(count * sizeof(char*)));
va_list v;
va_start(v, count);
int i;
for (i = 0; i < count; ++i) {
std::string str;
if (!Evaluate(state, argv[i], &str) ||
(args[i] = strdup(str.c_str())) == nullptr) {
va_end(v);
int j;
for (j = 0; j < i; ++j) {
free(args[j]);
}
free(args);
return -1;
}
*(va_arg(v, char**)) = args[i];
}
va_end(v);
free(args);
return 0;
}
// Evaluate the expressions in argv, giving 'count' Value* (the ... is
// zero or more Value** to put them in). If any expression evaluates
// to NULL, free the rest and return -1. Return 0 on success.
int ReadValueArgs(State* state, Expr* argv[], int count, ...) {
Value** args = new Value*[count];
va_list v;
va_start(v, count);
for (int i = 0; i < count; ++i) {
args[i] = EvaluateValue(state, argv[i]);
if (args[i] == NULL) {
va_end(v);
int j;
for (j = 0; j < i; ++j) {
delete args[j];
}
delete[] args;
return -1;
}
*(va_arg(v, Value**)) = args[i];
}
va_end(v);
delete[] args;
return 0;
}
// Evaluate the expressions in argv, returning an array of char*
// results. If any evaluate to NULL, free the rest and return NULL.
// The caller is responsible for freeing the returned array and the
// strings it contains.
char** ReadVarArgs(State* state, int argc, Expr* argv[]) {
char** args = (char**)malloc(argc * sizeof(char*));
for (int i = 0; i < argc; ++i) {
std::string str;
if (!Evaluate(state, argv[i], &str) ||
(args[i] = strdup(str.c_str())) == nullptr) {
for (int j = 0; j < i; ++j) {
free(args[j]);
}
free(args);
return NULL;
}
}
return args;
}
// Evaluate the expressions in argv, returning an array of Value*
// results. If any evaluate to NULL, free the rest and return NULL.
// The caller is responsible for freeing the returned array and the
// Values it contains.
Value** ReadValueVarArgs(State* state, int argc, Expr* argv[]) {
Value** args = new Value*[argc];
int i = 0;
for (i = 0; i < argc; ++i) {
args[i] = EvaluateValue(state, argv[i]);
if (args[i] == NULL) {
int j;
for (j = 0; j < i; ++j) {
delete args[j];
}
delete[] args;
return NULL;
}
}
return args;
}
// Use printf-style arguments to compose an error message to put into
// *state. Returns nullptr.
Value* ErrorAbort(State* state, const char* format, ...) {

View file

@ -128,30 +128,7 @@ bool ReadArgs(State* state, int argc, Expr* argv[], std::vector<std::string>* ar
// Evaluate the expressions in argv, and put the results of Value* in
// args. If any expression evaluate to nullptr, free the rest and return
// false. Return true on success.
bool ReadValueArgs(State* state, int argc, Expr* argv[],
std::vector<std::unique_ptr<Value>>* args);
// Evaluate the expressions in argv, giving 'count' char* (the ... is
// zero or more char** to put them in). If any expression evaluates
// to NULL, free the rest and return -1. Return 0 on success.
int ReadArgs(State* state, Expr* argv[], int count, ...);
// Evaluate the expressions in argv, giving 'count' Value* (the ... is
// zero or more Value** to put them in). If any expression evaluates
// to NULL, free the rest and return -1. Return 0 on success.
int ReadValueArgs(State* state, Expr* argv[], int count, ...);
// Evaluate the expressions in argv, returning an array of char*
// results. If any evaluate to NULL, free the rest and return NULL.
// The caller is responsible for freeing the returned array and the
// strings it contains.
char** ReadVarArgs(State* state, int argc, Expr* argv[]);
// Evaluate the expressions in argv, returning an array of Value*
// results. If any evaluate to NULL, free the rest and return NULL.
// The caller is responsible for freeing the returned array and the
// Values it contains.
Value** ReadValueVarArgs(State* state, int argc, Expr* argv[]);
bool ReadValueArgs(State* state, int argc, Expr* argv[], std::vector<std::unique_ptr<Value>>* args);
// Use printf-style arguments to compose an error message to put into
// *state. Returns NULL.

View file

@ -1368,18 +1368,15 @@ static Value* PerformBlockImageUpdate(const char* name, State* state, int /* arg
fprintf(stderr, "This update is a retry.\n");
}
Value* blockdev_filename = nullptr;
Value* transfer_list_value = nullptr;
Value* new_data_fn = nullptr;
Value* patch_data_fn = nullptr;
if (ReadValueArgs(state, argv, 4, &blockdev_filename, &transfer_list_value,
&new_data_fn, &patch_data_fn) < 0) {
return StringValue("");
std::vector<std::unique_ptr<Value>> args;
if (!ReadValueArgs(state, 4, argv, &args)) {
return nullptr;
}
std::unique_ptr<Value> blockdev_filename_holder(blockdev_filename);
std::unique_ptr<Value> transfer_list_value_holder(transfer_list_value);
std::unique_ptr<Value> new_data_fn_holder(new_data_fn);
std::unique_ptr<Value> patch_data_fn_holder(patch_data_fn);
const Value* blockdev_filename = args[0].get();
const Value* transfer_list_value = args[1].get();
const Value* new_data_fn = args[2].get();
const Value* patch_data_fn = args[3].get();
if (blockdev_filename->type != VAL_STRING) {
ErrorAbort(state, kArgsParsingFailure, "blockdev_filename argument to %s must be string",
@ -1689,14 +1686,13 @@ Value* BlockImageUpdateFn(const char* name, State* state, int argc, Expr* argv[]
}
Value* RangeSha1Fn(const char* name, State* state, int /* argc */, Expr* argv[]) {
Value* blockdev_filename;
Value* ranges;
if (ReadValueArgs(state, argv, 2, &blockdev_filename, &ranges) < 0) {
return StringValue("");
std::vector<std::unique_ptr<Value>> args;
if (!ReadValueArgs(state, 2, argv, &args)) {
return nullptr;
}
std::unique_ptr<Value> ranges_holder(ranges);
std::unique_ptr<Value> blockdev_filename_holder(blockdev_filename);
const Value* blockdev_filename = args[0].get();
const Value* ranges = args[1].get();
if (blockdev_filename->type != VAL_STRING) {
ErrorAbort(state, kArgsParsingFailure, "blockdev_filename argument to %s must be string",
@ -1751,14 +1747,14 @@ Value* RangeSha1Fn(const char* name, State* state, int /* argc */, Expr* argv[])
// if executes successfully and an empty string otherwise.
Value* CheckFirstBlockFn(const char* name, State* state, int argc, Expr* argv[]) {
Value* arg_filename;
if (ReadValueArgs(state, argv, 1, &arg_filename) < 0) {
std::vector<std::unique_ptr<Value>> args;
if (!ReadValueArgs(state, 1, argv, &args)) {
return nullptr;
}
std::unique_ptr<Value> filename(arg_filename);
if (filename->type != VAL_STRING) {
const Value* arg_filename = args[0].get();
if (arg_filename->type != VAL_STRING) {
ErrorAbort(state, kArgsParsingFailure, "filename argument to %s must be string", name);
return StringValue("");
}
@ -1799,15 +1795,13 @@ Value* CheckFirstBlockFn(const char* name, State* state, int argc, Expr* argv[])
Value* BlockImageRecoverFn(const char* name, State* state, int argc, Expr* argv[]) {
Value* arg_filename;
Value* arg_ranges;
if (ReadValueArgs(state, argv, 2, &arg_filename, &arg_ranges) < 0) {
return NULL;
std::vector<std::unique_ptr<Value>> args;
if (!ReadValueArgs(state, 2, argv, &args)) {
return nullptr;
}
std::unique_ptr<Value> filename(arg_filename);
std::unique_ptr<Value> ranges(arg_ranges);
const Value* filename = args[0].get();
const Value* ranges = args[1].get();
if (filename->type != VAL_STRING) {
ErrorAbort(state, kArgsParsingFailure, "filename argument to %s must be string", name);

File diff suppressed because it is too large Load diff