Remove malloc in edify functions

And switch them to std::vector & std::unique_ptr

Bug: 32117870
Test: recovery tests passed on sailfish
Change-Id: I5a45951c4bdf895be311d6d760e52e7a1b0798c3
diff --git a/edify/parser.yy b/edify/parser.yy
index 58a8dec..97205fe 100644
--- a/edify/parser.yy
+++ b/edify/parser.yy
@@ -19,6 +19,10 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <memory>
+#include <string>
+#include <vector>
+
 #include "expr.h"
 #include "yydefs.h"
 #include "parser.h"
@@ -26,8 +30,8 @@
 extern int gLine;
 extern int gColumn;
 
-void yyerror(Expr** root, int* error_count, const char* s);
-int yyparse(Expr** root, int* error_count);
+void yyerror(std::unique_ptr<Expr>* root, int* error_count, const char* s);
+int yyparse(std::unique_ptr<Expr>* root, int* error_count);
 
 struct yy_buffer_state;
 void yy_switch_to_buffer(struct yy_buffer_state* new_buffer);
@@ -38,17 +42,11 @@
 static Expr* Build(Function fn, YYLTYPE loc, size_t count, ...) {
     va_list v;
     va_start(v, count);
-    Expr* e = static_cast<Expr*>(malloc(sizeof(Expr)));
-    e->fn = fn;
-    e->name = "(operator)";
-    e->argc = count;
-    e->argv = static_cast<Expr**>(malloc(count * sizeof(Expr*)));
+    Expr* e = new Expr(fn, "(operator)", loc.start, loc.end);
     for (size_t i = 0; i < count; ++i) {
-        e->argv[i] = va_arg(v, Expr*);
+        e->argv.emplace_back(va_arg(v, Expr*));
     }
     va_end(v);
-    e->start = loc.start;
-    e->end = loc.end;
     return e;
 }
 
@@ -59,10 +57,7 @@
 %union {
     char* str;
     Expr* expr;
-    struct {
-        int argc;
-        Expr** argv;
-    } args;
+    std::vector<std::unique_ptr<Expr>>* args;
 }
 
 %token AND OR SUBSTR SUPERSTR EQ NE IF THEN ELSE ENDIF
@@ -70,7 +65,10 @@
 %type <expr> expr
 %type <args> arglist
 
-%parse-param {Expr** root}
+%destructor { delete $$; } expr
+%destructor { delete $$; } arglist
+
+%parse-param {std::unique_ptr<Expr>* root}
 %parse-param {int* error_count}
 %error-verbose
 
@@ -85,17 +83,11 @@
 
 %%
 
-input:  expr           { *root = $1; }
+input:  expr           { root->reset($1); }
 ;
 
 expr:  STRING {
-    $$ = static_cast<Expr*>(malloc(sizeof(Expr)));
-    $$->fn = Literal;
-    $$->name = $1;
-    $$->argc = 0;
-    $$->argv = NULL;
-    $$->start = @$.start;
-    $$->end = @$.end;
+    $$ = new Expr(Literal, $1, @$.start, @$.end);
 }
 |  '(' expr ')'                      { $$ = $2; $$->start=@$.start; $$->end=@$.end; }
 |  expr ';'                          { $$ = $1; $$->start=@1.start; $$->end=@1.end; }
@@ -110,41 +102,32 @@
 |  IF expr THEN expr ENDIF           { $$ = Build(IfElseFn, @$, 2, $2, $4); }
 |  IF expr THEN expr ELSE expr ENDIF { $$ = Build(IfElseFn, @$, 3, $2, $4, $6); }
 | STRING '(' arglist ')' {
-    $$ = static_cast<Expr*>(malloc(sizeof(Expr)));
-    $$->fn = FindFunction($1);
-    if ($$->fn == nullptr) {
-        char buffer[256];
-        snprintf(buffer, sizeof(buffer), "unknown function \"%s\"", $1);
-        yyerror(root, error_count, buffer);
+    Function fn = FindFunction($1);
+    if (fn == nullptr) {
+        std::string msg = "unknown function \"" + std::string($1) + "\"";
+        yyerror(root, error_count, msg.c_str());
         YYERROR;
     }
-    $$->name = $1;
-    $$->argc = $3.argc;
-    $$->argv = $3.argv;
-    $$->start = @$.start;
-    $$->end = @$.end;
+    $$ = new Expr(fn, $1, @$.start, @$.end);
+    $$->argv = std::move(*$3);
 }
 ;
 
 arglist:    /* empty */ {
-    $$.argc = 0;
-    $$.argv = NULL;
+    $$ = new std::vector<std::unique_ptr<Expr>>;
 }
 | expr {
-    $$.argc = 1;
-    $$.argv = static_cast<Expr**>(malloc(sizeof(Expr*)));
-    $$.argv[0] = $1;
+    $$ = new std::vector<std::unique_ptr<Expr>>;
+    $$->emplace_back($1);
 }
 | arglist ',' expr {
-    $$.argc = $1.argc + 1;
-    $$.argv = static_cast<Expr**>(realloc($$.argv, $$.argc * sizeof(Expr*)));
-    $$.argv[$$.argc-1] = $3;
+    $$->push_back(std::unique_ptr<Expr>($3));
 }
 ;
 
 %%
 
-void yyerror(Expr** root, int* error_count, const char* s) {
+void yyerror(std::unique_ptr<Expr>* root, int* error_count, const char* s) {
   if (strlen(s) == 0) {
     s = "syntax error";
   }
@@ -152,7 +135,7 @@
   ++*error_count;
 }
 
-int parse_string(const char* str, Expr** root, int* error_count) {
+int parse_string(const char* str, std::unique_ptr<Expr>* root, int* error_count) {
     yy_switch_to_buffer(yy_scan_string(str));
     return yyparse(root, error_count);
 }