14a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/*---------------------------------------------------------------------------*
24a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  ExpressionParser.c  *
34a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
44a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
54a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
64a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Licensed under the Apache License, Version 2.0 (the 'License');          *
74a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  you may not use this file except in compliance with the License.         *
84a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
94a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  You may obtain a copy of the License at                                  *
104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0                           *
114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  Unless required by applicable law or agreed to in writing, software      *
134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  distributed under the License is distributed on an 'AS IS' BASIS,        *
144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  See the License for the specific language governing permissions and      *
164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *  limitations under the License.                                           *
174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *                                                                           *
184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project *---------------------------------------------------------------------------*/
194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "SR_ExpressionParser.h"
214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project#include "plog.h"
224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Projectstatic const char* MTAG = __FILE__;
264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project/**
294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project * These are handlers for tokens. They modify state of the parser
304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project */
314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_NewStatement(ExpressionParser *self);
324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_Identifier(ExpressionParser *self);
334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_OpAssign(ExpressionParser *self);
344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_OpConcat(ExpressionParser *self);
354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_LBracket(ExpressionParser *self);
364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_ParamDelim(ExpressionParser *self);
374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_RBracket(ExpressionParser *self);
384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_ConditionalExpression_IfTrue(ExpressionParser *self);
394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_ConditionalExpression_Else(ExpressionParser *self);
404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_EndOfStatement(ExpressionParser *self, SymbolTable *st, ExpressionEvaluator *ee);
414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode EP_Init(ExpressionParser** self)
444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ESR_ReturnCode rc;
464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ExpressionParser* Interface;
474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (self == NULL)
494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    PLogError(L("ESR_INVALID_ARGUMENT"));
514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ESR_INVALID_ARGUMENT;
524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  Interface = NEW(ExpressionParser, MTAG);
554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (Interface == NULL)
564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    PLogError(L("ESR_OUT_OF_MEMORY"));
584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ESR_OUT_OF_MEMORY;
594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* create the hashtable for looking up the function callbacks */
624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHKLOG(rc, HashMapCreate(&Interface->pfunctions));
634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* register the built-in callbacks */
654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  Interface->next = &Interface->functions[0];
664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHKLOG(rc, EP_RegisterFunction(Interface, L("concat"), NULL, EE_concat));
674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHKLOG(rc, EP_RegisterFunction(Interface, L("conditional"), NULL, EE_conditional));
684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHKLOG(rc, EP_RegisterFunction(Interface, L("add"), NULL, EE_add));
694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHKLOG(rc, EP_RegisterFunction(Interface, L("subtract"), NULL, EE_subtract));
704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  Interface->needToExecuteFunction = ESR_FALSE;
714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  *self = Interface;
724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return ESR_SUCCESS;
734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  EP_Free(Interface);
754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return rc;
764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode EP_Free(ExpressionParser* self)
794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ESR_ReturnCode rc;
814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (self == NULL)
834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    PLogError(L("ESR_INVALID_ARGUMENT"));
854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ESR_INVALID_ARGUMENT;
864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHKLOG(rc, HashMapRemoveAll(self->pfunctions));
884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* free all the memory lots by simply resetting the next pointer */
904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  self->next = &self->functions[0];
914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* delete the hash table */
934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHKLOG(rc, HashMapDestroy(self->pfunctions));
944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FREE(self);
954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return ESR_SUCCESS;
964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return rc;
984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode EP_parse(ExpressionParser* parser, LexicalAnalyzer* lexAnalyzer,
1014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        SymbolTable* symtable, ExpressionEvaluator* evaluator,
1024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                        HashMap** hashmap)
1034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ESR_ReturnCode rc;
1054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t tokenLen;
1064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ESR_BOOL verbose = ESR_FALSE;
1074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ESR_BOOL sessionExists = ESR_FALSE;
1084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* init */
1104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHKLOG(rc, ST_reset(symtable)); /* reset the symbol table, for a new set of keys and values */
1114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHKLOG(rc, handle_NewStatement(parser));
1124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  while (ESR_TRUE)
1144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
1154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    CHKLOG(rc, LA_nextToken(lexAnalyzer, parser->ptokenBuf, &tokenLen));
1164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    if (!tokenLen)
1174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      break; /* no more tokens */
1184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    switch (parser->ptokenBuf[0])
1204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    {
1214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      case OP_ASSIGN:
1224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        CHKLOG(rc, handle_OpAssign(parser));
1234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        break;
1244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      case OP_CONCAT:
1254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        CHKLOG(rc, handle_OpConcat(parser));
1264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        break;
1274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      case LBRACKET:
1284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        CHKLOG(rc, handle_LBracket(parser));
1294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        break;
1304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      case PARAM_DELIM:
1314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        CHKLOG(rc, handle_ParamDelim(parser));
1324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        break;
1334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      case RBRACKET:
1344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        CHKLOG(rc, handle_RBracket(parser));
1354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        break;
1364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      case OP_CONDITION_IFTRUE:
1374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        CHKLOG(rc, handle_ConditionalExpression_IfTrue(parser));
1384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        break;
1394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      case OP_CONDITION_ELSE:
1404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        CHKLOG(rc, handle_ConditionalExpression_Else(parser));
1414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        break;
1424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      case EO_STATEMENT:
1434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        CHKLOG(rc, handle_EndOfStatement(parser, symtable, evaluator));
1444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        break;
1454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      default:
1464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        CHKLOG(rc, handle_Identifier(parser));
1474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        break;
1484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    }
1494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (rc == ESR_SUCCESS)
1524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    CHKLOG(rc, ST_Copy(symtable, *hashmap));
1534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else
1544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    *hashmap = NULL; /* don't give access to hashtable if something went wrong */
1554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return ESR_SUCCESS;
1564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
1584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHKLOG(rc, ESR_SessionExists(&sessionExists));
1594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (sessionExists)
1614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    rc = ESR_SessionGetBool(L("cmdline.semproc_verbose"), &verbose);
1624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  else
1634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    verbose = ESR_TRUE; /* apps like parseStringTest will not init session, but I want a
1644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                         descriptive error message regardless */
1654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (rc == ESR_NO_MATCH_ERROR)
1674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    rc = ESR_SUCCESS;
1684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (verbose)
1704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
1714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    PLogError(L("\n\nSemproc: error parsing symbol '%s'\nbefore: '%s'\nin script:\n%s\n\n"),
1724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project              parser->ptokenBuf,
1734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project              (lexAnalyzer->nextToken ? lexAnalyzer->nextToken : L("<end-of-script>")),
1744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project              lexAnalyzer->script);
1754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
1764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return rc;
1774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_NewStatement(ExpressionParser* self)
1804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* initially I want ptokenBuf to point to the lhs */
1824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  self->ptokenBuf = self->lhs;
1834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  self->state = LHS_REQUIRED;
1844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  self->idCount = 0;
1854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  self->pfunction = 0;
1864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return ESR_SUCCESS;
1874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
1884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_Identifier(ExpressionParser* self)
1904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
1914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ESR_ReturnCode rc;
1924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
1934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  switch (self->state)
1944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
1954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    case LHS_REQUIRED:
1964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->ptokenBuf = self->op;
1974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->state = OP_ASSIGN_REQUIRED;
1984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ESR_SUCCESS;
1994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    case IDENTIFIER_REQUIRED:
2004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->ptokenBuf = self->op;
2014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->state = OP_ANY_REQUIRED;
2024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->idCount++; /* index to the next id slot */
2034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ESR_SUCCESS;
2044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    default:
2054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      rc = ESR_INVALID_STATE;
2064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      PLogError(L("%s: state=%d - are there reserved chars in the tag?"), ESR_rc2str(rc), self->state);
2074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return rc;
2084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_OpAssign(ExpressionParser* self)
2124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ESR_ReturnCode rc;
2144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (self->state == OP_ASSIGN_REQUIRED)
2164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
2174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MEMCHK(rc, self->idCount, MAX_RHS_IDENTIFIERS - 1);
2184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    self->ptokenBuf = self->identifiers[self->idCount];
2194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    self->state = IDENTIFIER_REQUIRED;
2204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ESR_SUCCESS;
2214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return ESR_INVALID_STATE;
2234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
2244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return rc;
2254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_OpConcat(ExpressionParser* self)
2284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ESR_ReturnCode rc;
2304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  if (self->state == OP_ANY_REQUIRED)
2324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
2334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    MEMCHK(rc, self->idCount, MAX_RHS_IDENTIFIERS - 1);
2344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    /* pointer to function to carry out in the Expression Evaluator */
2354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    CHKLOG(rc, EP_LookUpFunction(self, "concat", &self->userData, &self->pfunction));
2364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    self->needToExecuteFunction = ESR_TRUE;
2374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    self->ptokenBuf = self->identifiers[self->idCount];
2384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    self->state = IDENTIFIER_REQUIRED;
2394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    return ESR_SUCCESS;
2404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return ESR_INVALID_STATE;
2424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
2434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return rc;
2444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_LBracket(ExpressionParser* self)
2474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ESR_ReturnCode rc;
2494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  switch (self->state)
2514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
2524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    case IDENTIFIER_REQUIRED :
2534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      MEMCHK(rc, self->idCount, MAX_RHS_IDENTIFIERS - 1);
2544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->ptokenBuf = self->identifiers[self->idCount];
2554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->state = IDENTIFIER_REQUIRED;
2564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ESR_SUCCESS;
2574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    case OP_ANY_REQUIRED :
2594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      MEMCHK(rc, self->idCount, MAX_RHS_IDENTIFIERS - 1);
2604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* the name of the function is stored as the most recent identifier encountered */
2624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      rc = EP_LookUpFunction(self, self->identifiers[self->idCount-1], &self->userData, &self->pfunction);
2634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (rc == ESR_NO_MATCH_ERROR)
2644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
2654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        self->pfunction = NULL;
2664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /*
2674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        PLogError(L("%s: Function '%s' is undefined"), ESR_rc2str(rc), self->identifiers[self->idCount-1]);
2684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return rc;
2694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        */
2704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
2714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->needToExecuteFunction = ESR_TRUE;
2724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* save the function name for future reference */
2734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      LSTRCPY(self->functionName, self->identifiers[self->idCount-1]);
2744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* now reuse old identifier slot */
2754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      --self->idCount;
2764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->ptokenBuf = self->identifiers[self->idCount];
2774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->state = IDENTIFIER_REQUIRED;
2794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ESR_SUCCESS;
2804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    default:
2814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ESR_INVALID_STATE;
2824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
2844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return rc;
2854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
2874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_ParamDelim(ExpressionParser* self)
2884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
2894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  switch (self->state)
2904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
2914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    case OP_ANY_REQUIRED :
2924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->ptokenBuf = self->identifiers[self->idCount];
2934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->state = IDENTIFIER_REQUIRED;
2944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ESR_SUCCESS;
2954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    default:
2964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ESR_INVALID_STATE;
2974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
2984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
2994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_RBracket(ExpressionParser* self)
3024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
3034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  switch (self->state)
3044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
3054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    case OP_ANY_REQUIRED :
3064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->ptokenBuf = self->op;
3074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->state = OP_ANY_REQUIRED;
3084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ESR_SUCCESS;
3094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    default:
3104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ESR_INVALID_STATE;
3114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
3134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_ConditionalExpression_IfTrue(ExpressionParser* self)
3154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
3164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ESR_ReturnCode rc;
3174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  switch (self->state)
3194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
3204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    case OP_ANY_REQUIRED :
3214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->ptokenBuf = self->identifiers[self->idCount];
3224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      CHKLOG(rc, EP_LookUpFunction(self, "conditional", &self->userData, &self->pfunction));
3234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->needToExecuteFunction = ESR_TRUE;
3244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->state = IDENTIFIER_REQUIRED;
3254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ESR_SUCCESS;
3264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    default:
3274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ESR_INVALID_STATE;
3284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
3304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return rc;
3314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
3324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_ConditionalExpression_Else(ExpressionParser* self)
3344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
3354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  switch (self->state)
3364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
3374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    case OP_ANY_REQUIRED :
3384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->ptokenBuf = self->identifiers[self->idCount];
3394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      self->state = IDENTIFIER_REQUIRED;
3404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ESR_SUCCESS;
3414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    default:
3424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ESR_INVALID_STATE;
3434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
3444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
3454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode handle_EndOfStatement(ExpressionParser* self, SymbolTable* symtable, ExpressionEvaluator* evaluator)
3484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
3494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t i;
3504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  LCHAR *operands[MAX_RHS_IDENTIFIERS];
3514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  LCHAR result[MAX_SEMPROC_VALUE];
3524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t resultLen;
3534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  LCHAR *p;
3544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  size_t offset;
3554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ESR_ReturnCode rc;
3564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  switch (self->state)
3584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  {
3594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    case OP_ANY_REQUIRED:
3604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* LHS cannot be a constant!!! */
3614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (self->lhs[0] == STRING_DELIM)
3624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
3634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        PLogError(L("ESR_INVALID_ARGUMENT: %s"), self->lhs);
3644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        return ESR_INVALID_ARGUMENT;
3654a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
3664a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3674a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3684a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* check to see whether identifiers are constants or variables
3694a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project       and remap to the value of variable when necessary */
3704a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      for (i = 0; i < self->idCount; i++)
3714a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
3724a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (self->identifiers[i][0] != STRING_DELIM)
3734a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          CHKLOG(rc, ST_getKeyValue(symtable, self->identifiers[i], &operands[i]));
3744a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else
3754a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
3764a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          /* be sure to remove the string delimiters before I work with identifiers */
3774a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3784a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          /* remove leading delim */
3794a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          p = operands[i] = &self->identifiers[i][1];
3804a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          offset = 0;
3814a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
3824a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          /* replace all \' by ' */
3834a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          while (*p != '\'')
3844a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          {
3854a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (*p == '\\')
3864a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
3874a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project              ++offset;
3884a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project              ++p;
3894a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
3904a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            if (offset > 0)
3914a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            {
3924a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project              *(p - offset) = *p;
3934a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            }
3944a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project            ++p;
3954a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          }
3964a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          *(p - offset) = '\0';
3974a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
3984a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
3994a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4004a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      /* if expression has to be evaluated */
4014a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      if (self->needToExecuteFunction)
4024a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
4034a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        if (self->pfunction)
4044a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        {
4054a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          result[0] = EO_STRING; /* empty it by default */
4064a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          resultLen = sizeof(result);
4074a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          CHKLOG(rc, (*self->pfunction)(self->functionName, operands, self->idCount, self->userData, result, &resultLen));
4084a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          CHKLOG(rc, ST_putKeyValue(symtable, self->lhs, result));
4094a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        }
4104a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        else
4114a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project          CHKLOG(rc, ST_putKeyValue(symtable, self->lhs, L("undefined")));
4124a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        self->needToExecuteFunction = ESR_FALSE;
4134a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
4144a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      else
4154a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      {
4164a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        /* if there is no function to execute */
4174a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project        CHKLOG(rc, ST_putKeyValue(symtable, self->lhs, operands[0]));
4184a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      }
4194a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return handle_NewStatement(self);
4204a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4214a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    case LHS_REQUIRED : /* for handling empty statements e.g. ";;;;" */
4224a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ESR_SUCCESS;
4234a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4244a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project    default:
4254a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      PLogError(L("ESR_INVALID_ARGUMENT: %d"), self->state);
4264a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project      return ESR_INVALID_STATE;
4274a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  }
4284a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
4294a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return rc;
4304a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4314a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4324a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode EP_RegisterFunction(ExpressionParser* self,
4334a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                   const LCHAR* name,
4344a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                   void* userData,
4354a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                   SR_SemprocFunctionPtr pfunction)
4364a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
4374a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FunctionCallback* callback = self->next++;
4384a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ESR_ReturnCode rc;
4394a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4404a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  MEMCHK(rc, self->next, &self->functions[MAX_FUNCTION_CALLBACKS-1]);
4414a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4424a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  callback->pfunction = pfunction;
4434a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  callback->userData = userData;
4444a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  /* creates a new entry if it does not already exist */
4454a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return HashMapPut(self->pfunctions, name, callback);
4464a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
4474a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return rc;
4484a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
4494a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4504a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectESR_ReturnCode EP_LookUpFunction(ExpressionParser* self,
4514a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                 LCHAR* name,
4524a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                 void** userData,
4534a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project                                 SR_SemprocFunctionPtr* pfunction)
4544a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project{
4554a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  ESR_ReturnCode rc;
4564a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  FunctionCallback* callback;
4574a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project
4584a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  CHK(rc, HashMapGet(self->pfunctions, name, (void**) &callback));
4594a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  *userData = callback->userData;
4604a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  *pfunction = callback->pfunction;
4614a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return ESR_SUCCESS;
4624a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source ProjectCLEANUP:
4634a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project  return rc;
4644a68b3365c8c50aa93505e99ead2565ab73dcdb0The Android Open Source Project}
465