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 25extern "C" { 26#endif 27 28#define MAX_STRING_LEN 1024 29 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}; 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. 71Value* 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. 78char* Evaluate(State* state, Expr* expr); 79 80// Glue to make an Expr out of a literal. 81Value* 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.) 86Value* ConcatFn(const char* name, State* state, int argc, Expr* argv[]); 87Value* LogicalAndFn(const char* name, State* state, int argc, Expr* argv[]); 88Value* LogicalOrFn(const char* name, State* state, int argc, Expr* argv[]); 89Value* LogicalNotFn(const char* name, State* state, int argc, Expr* argv[]); 90Value* SubstringFn(const char* name, State* state, int argc, Expr* argv[]); 91Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]); 92Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]); 93Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]); 94 95// Convenience function for building expressions with a fixed number 96// of arguments. 97Expr* Build(Function fn, YYLTYPE loc, int count, ...); 98 99// Global builtins, registered by RegisterBuiltins(). 100Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]); 101Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]); 102Value* 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). 107void SetError(const char* message); // makes a copy 108const char* GetError(); // retains ownership 109void ClearError(); 110 111 112typedef 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. 119void RegisterFunction(const char* name, Function fn); 120 121// Register all the builtins. 122void RegisterBuiltins(); 123 124// Call this after all calls to RegisterFunction() but before parsing 125// any scripts to finish building the function table. 126void FinishRegistration(); 127 128// Find the Function for a given name; return NULL if no such function 129// exists. 130Function 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. 138int 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. 143int 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. 149char** 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. 155Value** 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. 159Value* ErrorAbort(State* state, const char* format, ...) __attribute__((format(printf, 2, 3))); 160 161// Wrap a string into a Value, taking ownership of the string. 162Value* StringValue(char* str); 163 164// Free a Value object. 165void FreeValue(Value* v); 166 167int parse_string(const char* str, Expr** root, int* error_count); 168 169#ifdef __cplusplus 170} // extern "C" 171#endif 172 173#endif // _EXPRESSION_H 174