454// Evaluate the expressions in argv, returning an array of char*
455// results.  If any evaluate to NULL, free the rest and return NULL.
456// The caller is responsible for freeing the returned array and the
457// strings it contains.
458char** ReadVarArgs(State* state, int argc, Expr* argv[]) {
459    char** args = (char**)malloc(argc * sizeof(char*));
460    int i = 0;
461    for (i = 0; i < argc; ++i) {
462        args[i] = Evaluate(state, argv[i]);
463        if (args[i] == NULL) {
464            int j;
465            for (j = 0; j < i; ++j) {
466                free(args[j]);
467            }
468            free(args);
469            return NULL;
470        }
471    }
472    return args;
473}
argv의 entry들을 하나씩 Evaluate으로 패스. 

 

패스된 argv=expr을 받아서

35char* Evaluate(State* state, Expr* expr) {
36    Value* v = expr->fn(expr->name, state, expr->argc, expr->argv);
37    if (v == NULL) return NULL;
38    if (v->type != VAL_STRING) {
39        ErrorAbort(state, "expecting string, got value type %d", v->type);
40        FreeValue(v);
41        return NULL;
42    }
43    char* result = v->data;
44    free(v);
45    return result;
46}


Value *v에 expr->fn(expr->name, state, expr->argc, expr->argv) 를 assign시킴.

Value은 다음과 같은 구조체.

51typedef struct {
52    int type;
53    ssize_t size;
54    char* data;
55} Value;

 

expr은 Expr 구조체이며,

60struct Expr {
61    Function fn;
62    char* name;
63    int argc;
64    Expr** argv;
65    int start, end;

 

expr->fn은 Function 타입, Function은

57typedef Value* (*Function)(const char* name, State* state,
58                           int argc, Expr* argv[]);

형태로 정의됨.

type인 string인지 확인하고 아닐 경우, 에러 메세지를 state에 저장하고, string일 경우, 정상 진행.

마지막에 v->data를 리턴함.

이런 값들을 모아서 ReadVarArgs는 args 배열로 리턴.

 

 

expr.h

30typedef struct Expr Expr;
31
32typedef struct {
33    // Optional pointer to app-specific data; the core of edify never
34    // uses this value.
35    void* cookie;
36
37    // The source of the original script.  Must be NULL-terminated,
38    // and in writable memory (Evaluate may make temporary changes to
39    // it but will restore it when done).
40    char* script;
41
42    // The error message (if any) returned if the evaluation aborts.
43    // Should be NULL initially, will be either NULL or a malloc'd
44    // pointer after Evaluate() returns.
45    char* errmsg;
46} State;
47
48#define VAL_STRING  1  // data will be NULL-terminated; size doesn't count null
49#define VAL_BLOB    2
50
51typedef struct {
52    int type;
53    ssize_t size;
54    char* data;
55} Value;
56
57typedef Value* (*Function)(const char* name, State* state,
58                           int argc, Expr* argv[]);
59
60struct Expr {
61    Function fn;
62    char* name;
63    int argc;
64    Expr** argv;
65    int start, end;
66};

 

Posted by code cat