Home | History | Annotate | Download | only in edify
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef _EXPRESSION_H
     18 #define _EXPRESSION_H
     19 
     20 #include <unistd.h>
     21 
     22 #include "yydefs.h"
     23 
     24 #ifdef __cplusplus
     25 extern "C" {
     26 #endif
     27 
     28 #define MAX_STRING_LEN 1024
     29 
     30 typedef struct Expr Expr;
     31 
     32 typedef 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 
     51 typedef struct {
     52     int type;
     53     ssize_t size;
     54     char* data;
     55 } Value;
     56 
     57 typedef Value* (*Function)(const char* name, State* state,
     58                            int argc, Expr* argv[]);
     59 
     60 struct Expr {
     61     Function fn;
     62     char* name;
     63     int argc;
     64     Expr** argv;
     65     int start, end;
     66 };
     67 
     68 // Take one of the Expr*s passed to the function as an argument,
     69 // evaluate it, return the resulting Value.  The caller takes
     70 // ownership of the returned Value.
     71 Value* EvaluateValue(State* state, Expr* expr);
     72 
     73 // Take one of the Expr*s passed to the function as an argument,
     74 // evaluate it, assert that it is a string, and return the resulting
     75 // char*.  The caller takes ownership of the returned char*.  This is
     76 // a convenience function for older functions that want to deal only
     77 // with strings.
     78 char* Evaluate(State* state, Expr* expr);
     79 
     80 // Glue to make an Expr out of a literal.
     81 Value* Literal(const char* name, State* state, int argc, Expr* argv[]);
     82 
     83 // Functions corresponding to various syntactic sugar operators.
     84 // ("concat" is also available as a builtin function, to concatenate
     85 // more than two strings.)
     86 Value* ConcatFn(const char* name, State* state, int argc, Expr* argv[]);
     87 Value* LogicalAndFn(const char* name, State* state, int argc, Expr* argv[]);
     88 Value* LogicalOrFn(const char* name, State* state, int argc, Expr* argv[]);
     89 Value* LogicalNotFn(const char* name, State* state, int argc, Expr* argv[]);
     90 Value* SubstringFn(const char* name, State* state, int argc, Expr* argv[]);
     91 Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]);
     92 Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]);
     93 Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]);
     94 
     95 // Convenience function for building expressions with a fixed number
     96 // of arguments.
     97 Expr* Build(Function fn, YYLTYPE loc, int count, ...);
     98 
     99 // Global builtins, registered by RegisterBuiltins().
    100 Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]);
    101 Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]);
    102 Value* AbortFn(const char* name, State* state, int argc, Expr* argv[]);
    103 
    104 
    105 // For setting and getting the global error string (when returning
    106 // NULL from a function).
    107 void SetError(const char* message);  // makes a copy
    108 const char* GetError();              // retains ownership
    109 void ClearError();
    110 
    111 
    112 typedef struct {
    113   const char* name;
    114   Function fn;
    115 } NamedFunction;
    116 
    117 // Register a new function.  The same Function may be registered under
    118 // multiple names, but a given name should only be used once.
    119 void RegisterFunction(const char* name, Function fn);
    120 
    121 // Register all the builtins.
    122 void RegisterBuiltins();
    123 
    124 // Call this after all calls to RegisterFunction() but before parsing
    125 // any scripts to finish building the function table.
    126 void FinishRegistration();
    127 
    128 // Find the Function for a given name; return NULL if no such function
    129 // exists.
    130 Function FindFunction(const char* name);
    131 
    132 
    133 // --- convenience functions for use in functions ---
    134 
    135 // Evaluate the expressions in argv, giving 'count' char* (the ... is
    136 // zero or more char** to put them in).  If any expression evaluates
    137 // to NULL, free the rest and return -1.  Return 0 on success.
    138 int ReadArgs(State* state, Expr* argv[], int count, ...);
    139 
    140 // Evaluate the expressions in argv, giving 'count' Value* (the ... is
    141 // zero or more Value** to put them in).  If any expression evaluates
    142 // to NULL, free the rest and return -1.  Return 0 on success.
    143 int ReadValueArgs(State* state, Expr* argv[], int count, ...);
    144 
    145 // Evaluate the expressions in argv, returning an array of char*
    146 // results.  If any evaluate to NULL, free the rest and return NULL.
    147 // The caller is responsible for freeing the returned array and the
    148 // strings it contains.
    149 char** ReadVarArgs(State* state, int argc, Expr* argv[]);
    150 
    151 // Evaluate the expressions in argv, returning an array of Value*
    152 // results.  If any evaluate to NULL, free the rest and return NULL.
    153 // The caller is responsible for freeing the returned array and the
    154 // Values it contains.
    155 Value** ReadValueVarArgs(State* state, int argc, Expr* argv[]);
    156 
    157 // Use printf-style arguments to compose an error message to put into
    158 // *state.  Returns NULL.
    159 Value* ErrorAbort(State* state, const char* format, ...) __attribute__((format(printf, 2, 3)));
    160 
    161 // Wrap a string into a Value, taking ownership of the string.
    162 Value* StringValue(char* str);
    163 
    164 // Free a Value object.
    165 void FreeValue(Value* v);
    166 
    167 #ifdef __cplusplus
    168 }  // extern "C"
    169 #endif
    170 
    171 #endif  // _EXPRESSION_H
    172