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 #define MAX_STRING_LEN 1024 25 26 typedef struct Expr Expr; 27 28 typedef struct { 29 // Optional pointer to app-specific data; the core of edify never 30 // uses this value. 31 void* cookie; 32 33 // The source of the original script. Must be NULL-terminated, 34 // and in writable memory (Evaluate may make temporary changes to 35 // it but will restore it when done). 36 char* script; 37 38 // The error message (if any) returned if the evaluation aborts. 39 // Should be NULL initially, will be either NULL or a malloc'd 40 // pointer after Evaluate() returns. 41 char* errmsg; 42 } State; 43 44 #define VAL_STRING 1 // data will be NULL-terminated; size doesn't count null 45 #define VAL_BLOB 2 46 47 typedef struct { 48 int type; 49 ssize_t size; 50 char* data; 51 } Value; 52 53 typedef Value* (*Function)(const char* name, State* state, 54 int argc, Expr* argv[]); 55 56 struct Expr { 57 Function fn; 58 char* name; 59 int argc; 60 Expr** argv; 61 int start, end; 62 }; 63 64 // Take one of the Expr*s passed to the function as an argument, 65 // evaluate it, return the resulting Value. The caller takes 66 // ownership of the returned Value. 67 Value* EvaluateValue(State* state, Expr* expr); 68 69 // Take one of the Expr*s passed to the function as an argument, 70 // evaluate it, assert that it is a string, and return the resulting 71 // char*. The caller takes ownership of the returned char*. This is 72 // a convenience function for older functions that want to deal only 73 // with strings. 74 char* Evaluate(State* state, Expr* expr); 75 76 // Glue to make an Expr out of a literal. 77 Value* Literal(const char* name, State* state, int argc, Expr* argv[]); 78 79 // Functions corresponding to various syntactic sugar operators. 80 // ("concat" is also available as a builtin function, to concatenate 81 // more than two strings.) 82 Value* ConcatFn(const char* name, State* state, int argc, Expr* argv[]); 83 Value* LogicalAndFn(const char* name, State* state, int argc, Expr* argv[]); 84 Value* LogicalOrFn(const char* name, State* state, int argc, Expr* argv[]); 85 Value* LogicalNotFn(const char* name, State* state, int argc, Expr* argv[]); 86 Value* SubstringFn(const char* name, State* state, int argc, Expr* argv[]); 87 Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]); 88 Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]); 89 Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]); 90 91 // Convenience function for building expressions with a fixed number 92 // of arguments. 93 Expr* Build(Function fn, YYLTYPE loc, int count, ...); 94 95 // Global builtins, registered by RegisterBuiltins(). 96 Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]); 97 Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]); 98 Value* AbortFn(const char* name, State* state, int argc, Expr* argv[]); 99 100 101 // For setting and getting the global error string (when returning 102 // NULL from a function). 103 void SetError(const char* message); // makes a copy 104 const char* GetError(); // retains ownership 105 void ClearError(); 106 107 108 typedef struct { 109 const char* name; 110 Function fn; 111 } NamedFunction; 112 113 // Register a new function. The same Function may be registered under 114 // multiple names, but a given name should only be used once. 115 void RegisterFunction(const char* name, Function fn); 116 117 // Register all the builtins. 118 void RegisterBuiltins(); 119 120 // Call this after all calls to RegisterFunction() but before parsing 121 // any scripts to finish building the function table. 122 void FinishRegistration(); 123 124 // Find the Function for a given name; return NULL if no such function 125 // exists. 126 Function FindFunction(const char* name); 127 128 129 // --- convenience functions for use in functions --- 130 131 // Evaluate the expressions in argv, giving 'count' char* (the ... is 132 // zero or more char** to put them in). If any expression evaluates 133 // to NULL, free the rest and return -1. Return 0 on success. 134 int ReadArgs(State* state, Expr* argv[], int count, ...); 135 136 // Evaluate the expressions in argv, giving 'count' Value* (the ... is 137 // zero or more Value** to put them in). If any expression evaluates 138 // to NULL, free the rest and return -1. Return 0 on success. 139 int ReadValueArgs(State* state, Expr* argv[], int count, ...); 140 141 // Evaluate the expressions in argv, returning an array of char* 142 // results. If any evaluate to NULL, free the rest and return NULL. 143 // The caller is responsible for freeing the returned array and the 144 // strings it contains. 145 char** ReadVarArgs(State* state, int argc, Expr* argv[]); 146 147 // Evaluate the expressions in argv, returning an array of Value* 148 // results. If any evaluate to NULL, free the rest and return NULL. 149 // The caller is responsible for freeing the returned array and the 150 // Values it contains. 151 Value** ReadValueVarArgs(State* state, int argc, Expr* argv[]); 152 153 // Use printf-style arguments to compose an error message to put into 154 // *state. Returns NULL. 155 Value* ErrorAbort(State* state, char* format, ...); 156 157 // Wrap a string into a Value, taking ownership of the string. 158 Value* StringValue(char* str); 159 160 // Free a Value object. 161 void FreeValue(Value* v); 162 163 #endif // _EXPRESSION_H 164