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