Sat Jul 26 06:12:58 2008

Asterisk developer's documentation


ast_expr2.c

Go to the documentation of this file.
00001 /* A Bison parser, made by GNU Bison 2.1a.  */
00002 
00003 /* Skeleton parser for Yacc-like parsing with Bison,
00004    Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2, or (at your option)
00009    any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019    Boston, MA 02110-1301, USA.  */
00020 
00021 /* As a special exception, when this file is copied by Bison into a
00022    Bison output file, you may use that output file without restriction.
00023    This special exception was added by the Free Software Foundation
00024    in version 1.24 of Bison.  */
00025 
00026 /* C LALR(1) parser skeleton written by Richard Stallman, by
00027    simplifying the original so-called "semantic" parser.  */
00028 
00029 /* All symbols defined below should begin with yy or YY, to avoid
00030    infringing on user name space.  This should be done even for local
00031    variables, as they might otherwise be expanded by user macros.
00032    There are some unavoidable exceptions within include files to
00033    define necessary library symbols; they are noted "INFRINGES ON
00034    USER NAME SPACE" below.  */
00035 
00036 /* Identify Bison output.  */
00037 #define YYBISON 1
00038 
00039 /* Bison version.  */
00040 #define YYBISON_VERSION "2.1a"
00041 
00042 /* Skeleton name.  */
00043 #define YYSKELETON_NAME "yacc.c"
00044 
00045 /* Pure parsers.  */
00046 #define YYPURE 1
00047 
00048 /* Using locations.  */
00049 #define YYLSP_NEEDED 1
00050 
00051 /* Substitute the variable and function names.  */
00052 #define yyparse ast_yyparse
00053 #define yylex   ast_yylex
00054 #define yyerror ast_yyerror
00055 #define yylval  ast_yylval
00056 #define yychar  ast_yychar
00057 #define yydebug ast_yydebug
00058 #define yynerrs ast_yynerrs
00059 #define yylloc ast_yylloc
00060 
00061 /* Tokens.  */
00062 #ifndef YYTOKENTYPE
00063 # define YYTOKENTYPE
00064    /* Put the tokens into the symbol table, so that GDB and other debuggers
00065       know about them.  */
00066    enum yytokentype {
00067      TOK_COLONCOLON = 258,
00068      TOK_COND = 259,
00069      TOK_OR = 260,
00070      TOK_AND = 261,
00071      TOK_NE = 262,
00072      TOK_LE = 263,
00073      TOK_GE = 264,
00074      TOK_LT = 265,
00075      TOK_GT = 266,
00076      TOK_EQ = 267,
00077      TOK_MINUS = 268,
00078      TOK_PLUS = 269,
00079      TOK_MOD = 270,
00080      TOK_DIV = 271,
00081      TOK_MULT = 272,
00082      TOK_COMPL = 273,
00083      TOK_EQTILDE = 274,
00084      TOK_COLON = 275,
00085      TOK_LP = 276,
00086      TOK_RP = 277,
00087      TOKEN = 278
00088    };
00089 #endif
00090 /* Tokens.  */
00091 #define TOK_COLONCOLON 258
00092 #define TOK_COND 259
00093 #define TOK_OR 260
00094 #define TOK_AND 261
00095 #define TOK_NE 262
00096 #define TOK_LE 263
00097 #define TOK_GE 264
00098 #define TOK_LT 265
00099 #define TOK_GT 266
00100 #define TOK_EQ 267
00101 #define TOK_MINUS 268
00102 #define TOK_PLUS 269
00103 #define TOK_MOD 270
00104 #define TOK_DIV 271
00105 #define TOK_MULT 272
00106 #define TOK_COMPL 273
00107 #define TOK_EQTILDE 274
00108 #define TOK_COLON 275
00109 #define TOK_LP 276
00110 #define TOK_RP 277
00111 #define TOKEN 278
00112 
00113 
00114 
00115 
00116 /* Copy the first part of user declarations.  */
00117 #line 1 "ast_expr2.y"
00118 
00119 /* Written by Pace Willisson (pace@blitz.com) 
00120  * and placed in the public domain.
00121  *
00122  * Largely rewritten by J.T. Conklin (jtc@wimsey.com)
00123  *
00124  * And then overhauled twice by Steve Murphy (murf@digium.com)
00125  * to add double-quoted strings, allow mult. spaces, improve
00126  * error messages, and then to fold in a flex scanner for the 
00127  * yylex operation.
00128  *
00129  * $FreeBSD: src/bin/expr/expr.y,v 1.16 2000/07/22 10:59:36 se Exp $
00130  */
00131 
00132 #include "asterisk.h"
00133 
00134 #ifndef STANDALONE
00135 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 73143 $")
00136 #endif
00137 
00138 #include <sys/types.h>
00139 #include <stdio.h>
00140 #include <stdlib.h>
00141 #include <string.h>
00142 #include <locale.h>
00143 #include <unistd.h>
00144 #include <ctype.h>
00145 #if !defined(SOLARIS) && !defined(__CYGWIN__)
00146 /* #include <err.h> */
00147 #else
00148 #define quad_t int64_t
00149 #endif
00150 #include <errno.h>
00151 #include <regex.h>
00152 #include <limits.h>
00153 
00154 #include "asterisk/ast_expr.h"
00155 #include "asterisk/logger.h"
00156 
00157 #if defined(LONG_LONG_MIN) && !defined(QUAD_MIN)
00158 #define QUAD_MIN LONG_LONG_MIN
00159 #endif
00160 #if defined(LONG_LONG_MAX) && !defined(QUAD_MAX)
00161 #define QUAD_MAX LONG_LONG_MAX
00162 #endif
00163 
00164 #  if ! defined(QUAD_MIN)
00165 #   define QUAD_MIN     (-0x7fffffffffffffffLL-1)
00166 #  endif
00167 #  if ! defined(QUAD_MAX)
00168 #   define QUAD_MAX     (0x7fffffffffffffffLL)
00169 #  endif
00170 
00171 #define YYPARSE_PARAM parseio
00172 #define YYLEX_PARAM ((struct parse_io *)parseio)->scanner
00173 #define YYERROR_VERBOSE 1
00174 extern char extra_error_message[4095];
00175 extern int extra_error_message_supplied;
00176 
00177 enum valtype {
00178    AST_EXPR_integer, AST_EXPR_numeric_string, AST_EXPR_string
00179 } ;
00180 
00181 #ifdef STANDALONE
00182 void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...) __attribute__ ((format (printf,5,6)));
00183 #endif
00184 
00185 struct val {
00186    enum valtype type;
00187    union {
00188       char *s;
00189       quad_t i;
00190    } u;
00191 } ;
00192 
00193 typedef void *yyscan_t;
00194 
00195 struct parse_io
00196 {
00197    char *string;
00198    struct val *val;
00199    yyscan_t scanner;
00200 };
00201  
00202 static int     chk_div __P((quad_t, quad_t));
00203 static int     chk_minus __P((quad_t, quad_t, quad_t));
00204 static int     chk_plus __P((quad_t, quad_t, quad_t));
00205 static int     chk_times __P((quad_t, quad_t, quad_t));
00206 static void    free_value __P((struct val *));
00207 static int     is_zero_or_null __P((struct val *));
00208 static int     isstring __P((struct val *));
00209 static struct val *make_integer __P((quad_t));
00210 static struct val *make_str __P((const char *));
00211 static struct val *op_and __P((struct val *, struct val *));
00212 static struct val *op_colon __P((struct val *, struct val *));
00213 static struct val *op_eqtilde __P((struct val *, struct val *));
00214 static struct val *op_div __P((struct val *, struct val *));
00215 static struct val *op_eq __P((struct val *, struct val *));
00216 static struct val *op_ge __P((struct val *, struct val *));
00217 static struct val *op_gt __P((struct val *, struct val *));
00218 static struct val *op_le __P((struct val *, struct val *));
00219 static struct val *op_lt __P((struct val *, struct val *));
00220 static struct val *op_cond __P((struct val *, struct val *, struct val *));
00221 static struct val *op_minus __P((struct val *, struct val *));
00222 static struct val *op_negate __P((struct val *));
00223 static struct val *op_compl __P((struct val *));
00224 static struct val *op_ne __P((struct val *, struct val *));
00225 static struct val *op_or __P((struct val *, struct val *));
00226 static struct val *op_plus __P((struct val *, struct val *));
00227 static struct val *op_rem __P((struct val *, struct val *));
00228 static struct val *op_times __P((struct val *, struct val *));
00229 static quad_t     to_integer __P((struct val *));
00230 static void    to_string __P((struct val *));
00231 
00232 /* uh, if I want to predeclare yylex with a YYLTYPE, I have to predeclare the yyltype... sigh */
00233 typedef struct yyltype
00234 {
00235   int first_line;
00236   int first_column;
00237 
00238   int last_line;
00239   int last_column;
00240 } yyltype;
00241 
00242 # define YYLTYPE yyltype
00243 # define YYLTYPE_IS_TRIVIAL 1
00244 
00245 /* we will get warning about no prototype for yylex! But we can't
00246    define it here, we have no definition yet for YYSTYPE. */
00247 
00248 int      ast_yyerror(const char *,YYLTYPE *, struct parse_io *);
00249  
00250 /* I wanted to add args to the yyerror routine, so I could print out
00251    some useful info about the error. Not as easy as it looks, but it
00252    is possible. */
00253 #define ast_yyerror(x) ast_yyerror(x,&yyloc,parseio)
00254 #define DESTROY(x) {if((x)->type == AST_EXPR_numeric_string || (x)->type == AST_EXPR_string) free((x)->u.s); (x)->u.s = 0; free(x);}
00255 
00256 
00257 /* Enabling traces.  */
00258 #ifndef YYDEBUG
00259 # define YYDEBUG 0
00260 #endif
00261 
00262 /* Enabling verbose error messages.  */
00263 #ifdef YYERROR_VERBOSE
00264 # undef YYERROR_VERBOSE
00265 # define YYERROR_VERBOSE 1
00266 #else
00267 # define YYERROR_VERBOSE 0
00268 #endif
00269 
00270 /* Enabling the token table.  */
00271 #ifndef YYTOKEN_TABLE
00272 # define YYTOKEN_TABLE 0
00273 #endif
00274 
00275 #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
00276 typedef union YYSTYPE
00277 #line 147 "ast_expr2.y"
00278 {
00279    struct val *val;
00280 }
00281 /* Line 198 of yacc.c.  */
00282 #line 283 "ast_expr2.c"
00283    YYSTYPE;
00284 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
00285 # define YYSTYPE_IS_DECLARED 1
00286 # define YYSTYPE_IS_TRIVIAL 1
00287 #endif
00288 
00289 #if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
00290 typedef struct YYLTYPE
00291 {
00292   int first_line;
00293   int first_column;
00294   int last_line;
00295   int last_column;
00296 } YYLTYPE;
00297 # define yyltype YYLTYPE /* obsolescent; will be withdrawn */
00298 # define YYLTYPE_IS_DECLARED 1
00299 # define YYLTYPE_IS_TRIVIAL 1
00300 #endif
00301 
00302 
00303 /* Copy the second part of user declarations.  */
00304 #line 151 "ast_expr2.y"
00305 
00306 extern int     ast_yylex __P((YYSTYPE *, YYLTYPE *, yyscan_t));
00307 
00308 
00309 /* Line 221 of yacc.c.  */
00310 #line 311 "ast_expr2.c"
00311 
00312 #ifdef short
00313 # undef short
00314 #endif
00315 
00316 #ifdef YYTYPE_UINT8
00317 typedef YYTYPE_UINT8 yytype_uint8;
00318 #else
00319 typedef unsigned char yytype_uint8;
00320 #endif
00321 
00322 #ifdef YYTYPE_INT8
00323 typedef YYTYPE_INT8 yytype_int8;
00324 #elif (defined __STDC__ || defined __C99__FUNC__ \
00325      || defined __cplusplus || defined _MSC_VER)
00326 typedef signed char yytype_int8;
00327 #else
00328 typedef short int yytype_int8;
00329 #endif
00330 
00331 #ifdef YYTYPE_UINT16
00332 typedef YYTYPE_UINT16 yytype_uint16;
00333 #else
00334 typedef unsigned short int yytype_uint16;
00335 #endif
00336 
00337 #ifdef YYTYPE_INT16
00338 typedef YYTYPE_INT16 yytype_int16;
00339 #else
00340 typedef short int yytype_int16;
00341 #endif
00342 
00343 #ifndef YYSIZE_T
00344 # ifdef __SIZE_TYPE__
00345 #  define YYSIZE_T __SIZE_TYPE__
00346 # elif defined size_t
00347 #  define YYSIZE_T size_t
00348 # elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
00349      || defined __cplusplus || defined _MSC_VER)
00350 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
00351 #  define YYSIZE_T size_t
00352 # else
00353 #  define YYSIZE_T unsigned int
00354 # endif
00355 #endif
00356 
00357 #define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
00358 
00359 #ifndef YY_
00360 # if YYENABLE_NLS
00361 #  if ENABLE_NLS
00362 #   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
00363 #   define YY_(msgid) dgettext ("bison-runtime", msgid)
00364 #  endif
00365 # endif
00366 # ifndef YY_
00367 #  define YY_(msgid) msgid
00368 # endif
00369 #endif
00370 
00371 /* Suppress unused-variable warnings by "using" E.  */
00372 #if ! defined lint || defined __GNUC__
00373 # define YYUSE(e) ((void) (e))
00374 #else
00375 # define YYUSE(e) /* empty */
00376 #endif
00377 
00378 /* Identity function, used to suppress warnings about constant conditions.  */
00379 #ifndef lint
00380 # define YYID(n) (n)
00381 #else
00382 #if (defined __STDC__ || defined __C99__FUNC__ \
00383      || defined __cplusplus || defined _MSC_VER)
00384 static int
00385 YYID (int i)
00386 #else
00387 static int
00388 YYID (i)
00389     int i;
00390 #endif
00391 {
00392   return i;
00393 }
00394 #endif
00395 
00396 #if ! defined yyoverflow || YYERROR_VERBOSE
00397 
00398 /* The parser invokes alloca or malloc; define the necessary symbols.  */
00399 
00400 # ifdef YYSTACK_USE_ALLOCA
00401 #  if YYSTACK_USE_ALLOCA
00402 #   ifdef __GNUC__
00403 #    define YYSTACK_ALLOC __builtin_alloca
00404 #   elif defined __BUILTIN_VA_ARG_INCR
00405 #    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
00406 #   elif defined _AIX
00407 #    define YYSTACK_ALLOC __alloca
00408 #   elif defined _MSC_VER
00409 #    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
00410 #    define alloca _alloca
00411 #   else
00412 #    define YYSTACK_ALLOC alloca
00413 #    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
00414      || defined __cplusplus || defined _MSC_VER)
00415 #     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
00416 #     ifndef _STDLIB_H
00417 #      define _STDLIB_H 1
00418 #     endif
00419 #    endif
00420 #   endif
00421 #  endif
00422 # endif
00423 
00424 # ifdef YYSTACK_ALLOC
00425    /* Pacify GCC's `empty if-body' warning.  */
00426 #  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
00427 #  ifndef YYSTACK_ALLOC_MAXIMUM
00428     /* The OS might guarantee only one guard page at the bottom of the stack,
00429        and a page size can be as small as 4096 bytes.  So we cannot safely
00430        invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
00431        to allow for a few compiler-allocated temporary stack slots.  */
00432 #   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
00433 #  endif
00434 # else
00435 #  define YYSTACK_ALLOC YYMALLOC
00436 #  define YYSTACK_FREE YYFREE
00437 #  ifndef YYSTACK_ALLOC_MAXIMUM
00438 #   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
00439 #  endif
00440 #  ifdef __cplusplus
00441 extern "C" {
00442 #  endif
00443 #  ifndef YYMALLOC
00444 #   define YYMALLOC malloc
00445 #   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
00446      || defined __cplusplus || defined _MSC_VER)
00447 void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
00448 #   endif
00449 #  endif
00450 #  ifndef YYFREE
00451 #   define YYFREE free
00452 #   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
00453      || defined __cplusplus || defined _MSC_VER)
00454 void free (void *); /* INFRINGES ON USER NAME SPACE */
00455 #   endif
00456 #  endif
00457 #  ifdef __cplusplus
00458 }
00459 #  endif
00460 # endif
00461 #endif /* ! defined yyoverflow || YYERROR_VERBOSE */
00462 
00463 
00464 #if (! defined yyoverflow \
00465      && (! defined __cplusplus \
00466     || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
00467         && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
00468 
00469 /* A type that is properly aligned for any stack member.  */
00470 union yyalloc
00471 {
00472   yytype_int16 yyss;
00473   YYSTYPE yyvs;
00474     YYLTYPE yyls;
00475 };
00476 
00477 /* The size of the maximum gap between one aligned stack and the next.  */
00478 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
00479 
00480 /* The size of an array large to enough to hold all stacks, each with
00481    N elements.  */
00482 # define YYSTACK_BYTES(N) \
00483      ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
00484       + 2 * YYSTACK_GAP_MAXIMUM)
00485 
00486 /* Copy COUNT objects from FROM to TO.  The source and destination do
00487    not overlap.  */
00488 # ifndef YYCOPY
00489 #  if defined __GNUC__ && 1 < __GNUC__
00490 #   define YYCOPY(To, From, Count) \
00491       __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
00492 #  else
00493 #   define YYCOPY(To, From, Count)     \
00494       do             \
00495    {              \
00496      YYSIZE_T yyi;            \
00497      for (yyi = 0; yyi < (Count); yyi++)  \
00498        (To)[yyi] = (From)[yyi];     \
00499    }              \
00500       while (YYID (0))
00501 #  endif
00502 # endif
00503 
00504 /* Relocate STACK from its old location to the new one.  The
00505    local variables YYSIZE and YYSTACKSIZE give the old and new number of
00506    elements in the stack, and YYPTR gives the new location of the
00507    stack.  Advance YYPTR to a properly aligned location for the next
00508    stack.  */
00509 # define YYSTACK_RELOCATE(Stack)             \
00510     do                           \
00511       {                          \
00512    YYSIZE_T yynewbytes;                \
00513    YYCOPY (&yyptr->Stack, Stack, yysize);          \
00514    Stack = &yyptr->Stack;                 \
00515    yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
00516    yyptr += yynewbytes / sizeof (*yyptr);          \
00517       }                          \
00518     while (YYID (0))
00519 
00520 #endif
00521 
00522 /* YYFINAL -- State number of the termination state.  */
00523 #define YYFINAL  10
00524 /* YYLAST -- Last index in YYTABLE.  */
00525 #define YYLAST   140
00526 
00527 /* YYNTOKENS -- Number of terminals.  */
00528 #define YYNTOKENS  24
00529 /* YYNNTS -- Number of nonterminals.  */
00530 #define YYNNTS  3
00531 /* YYNRULES -- Number of rules.  */
00532 #define YYNRULES  23
00533 /* YYNRULES -- Number of states.  */
00534 #define YYNSTATES  46
00535 
00536 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
00537 #define YYUNDEFTOK  2
00538 #define YYMAXUTOK   278
00539 
00540 #define YYTRANSLATE(YYX)                  \
00541   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
00542 
00543 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
00544 static const yytype_uint8 yytranslate[] =
00545 {
00546        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00547        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00548        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00549        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00550        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00551        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00552        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00553        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00554        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00555        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00556        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00557        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00558        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00559        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00560        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00561        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00562        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00563        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00564        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00565        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00566        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00567        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00568        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00569        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00570        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00571        2,     2,     2,     2,     2,     2,     1,     2,     3,     4,
00572        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
00573       15,    16,    17,    18,    19,    20,    21,    22,    23
00574 };
00575 
00576 #if YYDEBUG
00577 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
00578    YYRHS.  */
00579 static const yytype_uint8 yyprhs[] =
00580 {
00581        0,     0,     3,     5,     6,     8,    12,    16,    20,    24,
00582       28,    32,    36,    40,    44,    48,    52,    55,    58,    62,
00583       66,    70,    74,    78
00584 };
00585 
00586 /* YYRHS -- A `-1'-separated list of the rules' RHS.  */
00587 static const yytype_int8 yyrhs[] =
00588 {
00589       25,     0,    -1,    26,    -1,    -1,    23,    -1,    21,    26,
00590       22,    -1,    26,     5,    26,    -1,    26,     6,    26,    -1,
00591       26,    12,    26,    -1,    26,    11,    26,    -1,    26,    10,
00592       26,    -1,    26,     9,    26,    -1,    26,     8,    26,    -1,
00593       26,     7,    26,    -1,    26,    14,    26,    -1,    26,    13,
00594       26,    -1,    13,    26,    -1,    18,    26,    -1,    26,    17,
00595       26,    -1,    26,    16,    26,    -1,    26,    15,    26,    -1,
00596       26,    20,    26,    -1,    26,    19,    26,    -1,    26,     4,
00597       26,     3,    26,    -1
00598 };
00599 
00600 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
00601 static const yytype_uint16 yyrline[] =
00602 {
00603        0,   175,   175,   183,   190,   191,   195,   199,   203,   207,
00604      211,   215,   219,   223,   227,   231,   235,   239,   243,   247,
00605      251,   255,   259,   263
00606 };
00607 #endif
00608 
00609 #if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
00610 /* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
00611    First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
00612 static const char *const yytname[] =
00613 {
00614   "$end", "error", "$undefined", "TOK_COLONCOLON", "TOK_COND", "TOK_OR",
00615   "TOK_AND", "TOK_NE", "TOK_LE", "TOK_GE", "TOK_LT", "TOK_GT", "TOK_EQ",
00616   "TOK_MINUS", "TOK_PLUS", "TOK_MOD", "TOK_DIV", "TOK_MULT", "TOK_COMPL",
00617   "TOK_EQTILDE", "TOK_COLON", "TOK_LP", "TOK_RP", "TOKEN", "$accept",
00618   "start", "expr", 0
00619 };
00620 #endif
00621 
00622 # ifdef YYPRINT
00623 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
00624    token YYLEX-NUM.  */
00625 static const yytype_uint16 yytoknum[] =
00626 {
00627        0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
00628      265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
00629      275,   276,   277,   278
00630 };
00631 # endif
00632 
00633 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
00634 static const yytype_uint8 yyr1[] =
00635 {
00636        0,    24,    25,    25,    26,    26,    26,    26,    26,    26,
00637       26,    26,    26,    26,    26,    26,    26,    26,    26,    26,
00638       26,    26,    26,    26
00639 };
00640 
00641 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
00642 static const yytype_uint8 yyr2[] =
00643 {
00644        0,     2,     1,     0,     1,     3,     3,     3,     3,     3,
00645        3,     3,     3,     3,     3,     3,     2,     2,     3,     3,
00646        3,     3,     3,     5
00647 };
00648 
00649 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
00650    STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
00651    means the default is an error.  */
00652 static const yytype_uint8 yydefact[] =
00653 {
00654        3,     0,     0,     0,     4,     0,     2,    16,    17,     0,
00655        1,     0,     0,     0,     0,     0,     0,     0,     0,     0,
00656        0,     0,     0,     0,     0,     0,     0,     5,     0,     6,
00657        7,    13,    12,    11,    10,     9,     8,    15,    14,    20,
00658       19,    18,    22,    21,     0,    23
00659 };
00660 
00661 /* YYDEFGOTO[NTERM-NUM].  */
00662 static const yytype_int8 yydefgoto[] =
00663 {
00664       -1,     5,     6
00665 };
00666 
00667 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
00668    STATE-NUM.  */
00669 #define YYPACT_NINF -13
00670 static const yytype_int8 yypact[] =
00671 {
00672      109,   109,   109,   109,   -13,     6,    59,   106,   106,    22,
00673      -13,   109,   109,   109,   109,   109,   109,   109,   109,   109,
00674      109,   109,   109,   109,   109,   109,   109,   -13,    42,    90,
00675      104,   120,   120,   120,   120,   120,   120,   -12,   -12,   106,
00676      106,   106,   -13,   -13,   109,    75
00677 };
00678 
00679 /* YYPGOTO[NTERM-NUM].  */
00680 static const yytype_int8 yypgoto[] =
00681 {
00682      -13,   -13,    -1
00683 };
00684 
00685 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
00686    positive, shift that token.  If negative, reduce the rule which
00687    number is the opposite.  If zero, do what YYDEFACT says.
00688    If YYTABLE_NINF, syntax error.  */
00689 #define YYTABLE_NINF -1
00690 static const yytype_uint8 yytable[] =
00691 {
00692        7,     8,     9,    22,    23,    24,    10,    25,    26,     0,
00693       28,    29,    30,    31,    32,    33,    34,    35,    36,    37,
00694       38,    39,    40,    41,    42,    43,    11,    12,    13,    14,
00695       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
00696        0,    25,    26,    45,    27,    44,    11,    12,    13,    14,
00697       15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
00698        0,    25,    26,    11,    12,    13,    14,    15,    16,    17,
00699       18,    19,    20,    21,    22,    23,    24,     0,    25,    26,
00700       12,    13,    14,    15,    16,    17,    18,    19,    20,    21,
00701       22,    23,    24,     0,    25,    26,    13,    14,    15,    16,
00702       17,    18,    19,    20,    21,    22,    23,    24,     0,    25,
00703       26,    14,    15,    16,    17,    18,    19,    20,    21,    22,
00704       23,    24,     1,    25,    26,    25,    26,     2,     0,     0,
00705        3,     0,     4,    20,    21,    22,    23,    24,     0,    25,
00706       26
00707 };
00708 
00709 static const yytype_int8 yycheck[] =
00710 {
00711        1,     2,     3,    15,    16,    17,     0,    19,    20,    -1,
00712       11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
00713       21,    22,    23,    24,    25,    26,     4,     5,     6,     7,
00714        8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
00715       -1,    19,    20,    44,    22,     3,     4,     5,     6,     7,
00716        8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
00717       -1,    19,    20,     4,     5,     6,     7,     8,     9,    10,
00718       11,    12,    13,    14,    15,    16,    17,    -1,    19,    20,
00719        5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
00720       15,    16,    17,    -1,    19,    20,     6,     7,     8,     9,
00721       10,    11,    12,    13,    14,    15,    16,    17,    -1,    19,
00722       20,     7,     8,     9,    10,    11,    12,    13,    14,    15,
00723       16,    17,    13,    19,    20,    19,    20,    18,    -1,    -1,
00724       21,    -1,    23,    13,    14,    15,    16,    17,    -1,    19,
00725       20
00726 };
00727 
00728 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
00729    symbol of state STATE-NUM.  */
00730 static const yytype_uint8 yystos[] =
00731 {
00732        0,    13,    18,    21,    23,    25,    26,    26,    26,    26,
00733        0,     4,     5,     6,     7,     8,     9,    10,    11,    12,
00734       13,    14,    15,    16,    17,    19,    20,    22,    26,    26,
00735       26,    26,    26,    26,    26,    26,    26,    26,    26,    26,
00736       26,    26,    26,    26,     3,    26
00737 };
00738 
00739 #define yyerrok      (yyerrstatus = 0)
00740 #define yyclearin (yychar = YYEMPTY)
00741 #define YYEMPTY      (-2)
00742 #define YYEOF     0
00743 
00744 #define YYACCEPT  goto yyacceptlab
00745 #define YYABORT      goto yyabortlab
00746 #define YYERROR      goto yyerrorlab
00747 
00748 
00749 /* Like YYERROR except do call yyerror.  This remains here temporarily
00750    to ease the transition to the new meaning of YYERROR, for GCC.
00751    Once GCC version 2 has supplanted version 1, this can go.  */
00752 
00753 #define YYFAIL    goto yyerrlab
00754 
00755 #define YYRECOVERING()  (!!yyerrstatus)
00756 
00757 #define YYBACKUP(Token, Value)               \
00758 do                      \
00759   if (yychar == YYEMPTY && yylen == 1)          \
00760     {                      \
00761       yychar = (Token);                \
00762       yylval = (Value);                \
00763       yytoken = YYTRANSLATE (yychar);           \
00764       YYPOPSTACK (1);                  \
00765       goto yybackup;                \
00766     }                      \
00767   else                        \
00768     {                      \
00769       yyerror (YY_("syntax error: cannot back up")); \
00770       YYERROR;                   \
00771     }                      \
00772 while (YYID (0))
00773 
00774 
00775 #define YYTERROR  1
00776 #define YYERRCODE 256
00777 
00778 
00779 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
00780    If N is 0, then set CURRENT to the empty location which ends
00781    the previous symbol: RHS[0] (always defined).  */
00782 
00783 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
00784 #ifndef YYLLOC_DEFAULT
00785 # define YYLLOC_DEFAULT(Current, Rhs, N)           \
00786     do                           \
00787       if (YYID (N))                                                    \
00788    {                       \
00789      (Current).first_line   = YYRHSLOC (Rhs, 1).first_line; \
00790      (Current).first_column = YYRHSLOC (Rhs, 1).first_column;  \
00791      (Current).last_line    = YYRHSLOC (Rhs, N).last_line;     \
00792      (Current).last_column  = YYRHSLOC (Rhs, N).last_column;   \
00793    }                       \
00794       else                       \
00795    {                       \
00796      (Current).first_line   = (Current).last_line   =    \
00797        YYRHSLOC (Rhs, 0).last_line;          \
00798      (Current).first_column = (Current).last_column =    \
00799        YYRHSLOC (Rhs, 0).last_column;           \
00800    }                       \
00801     while (YYID (0))
00802 #endif
00803 
00804 
00805 /* YY_LOCATION_PRINT -- Print the location on the stream.
00806    This macro was not mandated originally: define only if we know
00807    we won't break user code: when these are the locations we know.  */
00808 
00809 #ifndef YY_LOCATION_PRINT
00810 # if YYLTYPE_IS_TRIVIAL
00811 #  define YY_LOCATION_PRINT(File, Loc)       \
00812      fprintf (File, "%d.%d-%d.%d",        \
00813          (Loc).first_line, (Loc).first_column,  \
00814          (Loc).last_line,  (Loc).last_column)
00815 # else
00816 #  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
00817 # endif
00818 #endif
00819 
00820 
00821 /* YYLEX -- calling `yylex' with the right arguments.  */
00822 
00823 #ifdef YYLEX_PARAM
00824 # define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
00825 #else
00826 # define YYLEX yylex (&yylval, &yylloc)
00827 #endif
00828 
00829 /* Enable debugging if requested.  */
00830 #if YYDEBUG
00831 
00832 # ifndef YYFPRINTF
00833 #  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
00834 #  define YYFPRINTF fprintf
00835 # endif
00836 
00837 # define YYDPRINTF(Args)         \
00838 do {                 \
00839   if (yydebug)             \
00840     YYFPRINTF Args;           \
00841 } while (YYID (0))
00842 
00843 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)           \
00844 do {                            \
00845   if (yydebug)                        \
00846     {                           \
00847       YYFPRINTF (stderr, "%s ", Title);                 \
00848       yy_symbol_print (stderr,                    \
00849         Type, Value, Location); \
00850       YYFPRINTF (stderr, "\n");                   \
00851     }                           \
00852 } while (YYID (0))
00853 
00854 
00855 /*--------------------------------.
00856 | Print this symbol on YYOUTPUT.  |
00857 `--------------------------------*/
00858 
00859 /*ARGSUSED*/
00860 #if (defined __STDC__ || defined __C99__FUNC__ \
00861      || defined __cplusplus || defined _MSC_VER)
00862 static void
00863 yy_symbol_value_print (FILE *yyoutput, int yytype, const YYSTYPE * const yyvaluep, const YYLTYPE * const yylocationp)
00864 #else
00865 static void
00866 yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp)
00867     FILE *yyoutput;
00868     int yytype;
00869     const YYSTYPE * const yyvaluep;
00870     const YYLTYPE * const yylocationp;
00871 #endif
00872 {
00873   if (!yyvaluep)
00874     return;
00875   YYUSE (yylocationp);
00876 # ifdef YYPRINT
00877   if (yytype < YYNTOKENS)
00878     YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
00879 # else
00880   YYUSE (yyoutput);
00881 # endif
00882   switch (yytype)
00883     {
00884       default:
00885    break;
00886     }
00887 }
00888 
00889 
00890 /*--------------------------------.
00891 | Print this symbol on YYOUTPUT.  |
00892 `--------------------------------*/
00893 
00894 #if (defined __STDC__ || defined __C99__FUNC__ \
00895      || defined __cplusplus || defined _MSC_VER)
00896 static void
00897 yy_symbol_print (FILE *yyoutput, int yytype, const YYSTYPE * const yyvaluep, const YYLTYPE * const yylocationp)
00898 #else
00899 static void
00900 yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp)
00901     FILE *yyoutput;
00902     int yytype;
00903     const YYSTYPE * const yyvaluep;
00904     const YYLTYPE * const yylocationp;
00905 #endif
00906 {
00907   if (yytype < YYNTOKENS)
00908     YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
00909   else
00910     YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
00911 
00912   YY_LOCATION_PRINT (yyoutput, *yylocationp);
00913   YYFPRINTF (yyoutput, ": ");
00914   yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
00915   YYFPRINTF (yyoutput, ")");
00916 }
00917 
00918 /*------------------------------------------------------------------.
00919 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
00920 | TOP (included).                                                   |
00921 `------------------------------------------------------------------*/
00922 
00923 #if (defined __STDC__ || defined __C99__FUNC__ \
00924      || defined __cplusplus || defined _MSC_VER)
00925 static void
00926 yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
00927 #else
00928 static void
00929 yy_stack_print (bottom, top)
00930     yytype_int16 *bottom;
00931     yytype_int16 *top;
00932 #endif
00933 {
00934   YYFPRINTF (stderr, "Stack now");
00935   for (; bottom <= top; ++bottom)
00936     YYFPRINTF (stderr, " %d", *bottom);
00937   YYFPRINTF (stderr, "\n");
00938 }
00939 
00940 # define YY_STACK_PRINT(Bottom, Top)            \
00941 do {                       \
00942   if (yydebug)                   \
00943     yy_stack_print ((Bottom), (Top));           \
00944 } while (YYID (0))
00945 
00946 
00947 /*------------------------------------------------.
00948 | Report that the YYRULE is going to be reduced.  |
00949 `------------------------------------------------*/
00950 
00951 #if (defined __STDC__ || defined __C99__FUNC__ \
00952      || defined __cplusplus || defined _MSC_VER)
00953 static void
00954 yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule)
00955 #else
00956 static void
00957 yy_reduce_print (yyvsp, yylsp, yyrule
00958          )
00959     YYSTYPE *yyvsp;
00960     YYLTYPE *yylsp;
00961     int yyrule;
00962 #endif
00963 {
00964   int yynrhs = yyr2[yyrule];
00965   int yyi;
00966   unsigned long int yylno = yyrline[yyrule];
00967   YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
00968         yyrule - 1, yylno);
00969   /* The symbols being reduced.  */
00970   for (yyi = 0; yyi < yynrhs; yyi++)
00971     {
00972       fprintf (stderr, "   $%d = ", yyi + 1);
00973       yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
00974              &(yyvsp[(yyi + 1) - (yynrhs)])
00975              , &(yylsp[(yyi + 1) - (yynrhs)])             );
00976       fprintf (stderr, "\n");
00977     }
00978 }
00979 
00980 # define YY_REDUCE_PRINT(Rule)      \
00981 do {              \
00982   if (yydebug)          \
00983     yy_reduce_print (yyvsp, yylsp, Rule); \
00984 } while (YYID (0))
00985 
00986 /* Nonzero means print parse trace.  It is left uninitialized so that
00987    multiple parsers can coexist.  */
00988 int yydebug;
00989 #else /* !YYDEBUG */
00990 # define YYDPRINTF(Args)
00991 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
00992 # define YY_STACK_PRINT(Bottom, Top)
00993 # define YY_REDUCE_PRINT(Rule)
00994 #endif /* !YYDEBUG */
00995 
00996 
00997 /* YYINITDEPTH -- initial size of the parser's stacks.  */
00998 #ifndef  YYINITDEPTH
00999 # define YYINITDEPTH 200
01000 #endif
01001 
01002 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
01003    if the built-in stack extension method is used).
01004 
01005    Do not make this value too large; the results are undefined if
01006    YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
01007    evaluated with infinite-precision integer arithmetic.  */
01008 
01009 #ifndef YYMAXDEPTH
01010 # define YYMAXDEPTH 10000
01011 #endif
01012 
01013 
01014 
01015 #if YYERROR_VERBOSE
01016 
01017 # ifndef yystrlen
01018 #  if defined __GLIBC__ && defined _STRING_H
01019 #   define yystrlen strlen
01020 #  else
01021 /* Return the length of YYSTR.  */
01022 #if (defined __STDC__ || defined __C99__FUNC__ \
01023      || defined __cplusplus || defined _MSC_VER)
01024 static YYSIZE_T
01025 yystrlen (const char *yystr)
01026 #else
01027 static YYSIZE_T
01028 yystrlen (yystr)
01029     const char *yystr;
01030 #endif
01031 {
01032   YYSIZE_T yylen;
01033   for (yylen = 0; yystr[yylen]; yylen++)
01034     continue;
01035   return yylen;
01036 }
01037 #  endif
01038 # endif
01039 
01040 # ifndef yystpcpy
01041 #  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
01042 #   define yystpcpy stpcpy
01043 #  else
01044 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
01045    YYDEST.  */
01046 #if (defined __STDC__ || defined __C99__FUNC__ \
01047      || defined __cplusplus || defined _MSC_VER)
01048 static char *
01049 yystpcpy (char *yydest, const char *yysrc)
01050 #else
01051 static char *
01052 yystpcpy (yydest, yysrc)
01053     char *yydest;
01054     const char *yysrc;
01055 #endif
01056 {
01057   char *yyd = yydest;
01058   const char *yys = yysrc;
01059 
01060   while ((*yyd++ = *yys++) != '\0')
01061     continue;
01062 
01063   return yyd - 1;
01064 }
01065 #  endif
01066 # endif
01067 
01068 # ifndef yytnamerr
01069 /* Copy to YYRES the contents of YYSTR after stripping away unnecessary
01070    quotes and backslashes, so that it's suitable for yyerror.  The
01071    heuristic is that double-quoting is unnecessary unless the string
01072    contains an apostrophe, a comma, or backslash (other than
01073    backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
01074    null, do not copy; instead, return the length of what the result
01075    would have been.  */
01076 static YYSIZE_T
01077 yytnamerr (char *yyres, const char *yystr)
01078 {
01079   if (*yystr == '"')
01080     {
01081       size_t yyn = 0;
01082       char const *yyp = yystr;
01083 
01084       for (;;)
01085    switch (*++yyp)
01086      {
01087      case '\'':
01088      case ',':
01089        goto do_not_strip_quotes;
01090 
01091      case '\\':
01092        if (*++yyp != '\\')
01093          goto do_not_strip_quotes;
01094        /* Fall through.  */
01095      default:
01096        if (yyres)
01097          yyres[yyn] = *yyp;
01098        yyn++;
01099        break;
01100 
01101      case '"':
01102        if (yyres)
01103          yyres[yyn] = '\0';
01104        return yyn;
01105      }
01106     do_not_strip_quotes: ;
01107     }
01108 
01109   if (! yyres)
01110     return yystrlen (yystr);
01111 
01112   return yystpcpy (yyres, yystr) - yyres;
01113 }
01114 # endif
01115 
01116 /* Copy into YYRESULT an error message about the unexpected token
01117    YYCHAR while in state YYSTATE.  Return the number of bytes copied,
01118    including the terminating null byte.  If YYRESULT is null, do not
01119    copy anything; just return the number of bytes that would be
01120    copied.  As a special case, return 0 if an ordinary "syntax error"
01121    message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
01122    size calculation.  */
01123 static YYSIZE_T
01124 yysyntax_error (char *yyresult, int yystate, int yychar)
01125 {
01126   int yyn = yypact[yystate];
01127 
01128   if (! (YYPACT_NINF < yyn && yyn < YYLAST))
01129     return 0;
01130   else
01131     {
01132       int yytype = YYTRANSLATE (yychar);
01133       YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
01134       YYSIZE_T yysize = yysize0;
01135       YYSIZE_T yysize1;
01136       int yysize_overflow = 0;
01137       enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
01138       char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
01139       int yyx;
01140 
01141 # if 0
01142       /* This is so xgettext sees the translatable formats that are
01143     constructed on the fly.  */
01144       YY_("syntax error, unexpected %s");
01145       YY_("syntax error, unexpected %s, expecting %s");
01146       YY_("syntax error, unexpected %s, expecting %s or %s");
01147       YY_("syntax error, unexpected %s, expecting %s or %s or %s");
01148       YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
01149 # endif
01150       char *yyfmt;
01151       char const *yyf;
01152       static char const yyunexpected[] = "syntax error, unexpected %s";
01153       static char const yyexpecting[] = ", expecting %s";
01154       static char const yyor[] = " or %s";
01155       char yyformat[sizeof yyunexpected
01156           + sizeof yyexpecting - 1
01157           + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
01158              * (sizeof yyor - 1))];
01159       char const *yyprefix = yyexpecting;
01160 
01161       /* Start YYX at -YYN if negative to avoid negative indexes in
01162     YYCHECK.  */
01163       int yyxbegin = yyn < 0 ? -yyn : 0;
01164 
01165       /* Stay within bounds of both yycheck and yytname.  */
01166       int yychecklim = YYLAST - yyn;
01167       int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
01168       int yycount = 1;
01169 
01170       yyarg[0] = yytname[yytype];
01171       yyfmt = yystpcpy (yyformat, yyunexpected);
01172 
01173       for (yyx = yyxbegin; yyx < yyxend; ++yyx)
01174    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
01175      {
01176        if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
01177          {
01178       yycount = 1;
01179       yysize = yysize0;
01180       yyformat[sizeof yyunexpected - 1] = '\0';
01181       break;
01182          }
01183        yyarg[yycount++] = yytname[yyx];
01184        yysize1 = yysize + yytnamerr (0, yytname[yyx]);
01185        yysize_overflow |= (yysize1 < yysize);
01186        yysize = yysize1;
01187        yyfmt = yystpcpy (yyfmt, yyprefix);
01188        yyprefix = yyor;
01189      }
01190 
01191       yyf = YY_(yyformat);
01192       yysize1 = yysize + yystrlen (yyf);
01193       yysize_overflow |= (yysize1 < yysize);
01194       yysize = yysize1;
01195 
01196       if (yysize_overflow)
01197    return YYSIZE_MAXIMUM;
01198 
01199       if (yyresult)
01200    {
01201      /* Avoid sprintf, as that infringes on the user's name space.
01202         Don't have undefined behavior even if the translation
01203         produced a string with the wrong number of "%s"s.  */
01204      char *yyp = yyresult;
01205      int yyi = 0;
01206      while ((*yyp = *yyf) != '\0')
01207        {
01208          if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
01209       {
01210         yyp += yytnamerr (yyp, yyarg[yyi++]);
01211         yyf += 2;
01212       }
01213          else
01214       {
01215         yyp++;
01216         yyf++;
01217       }
01218        }
01219    }
01220       return yysize;
01221     }
01222 }
01223 #endif /* YYERROR_VERBOSE */
01224 
01225 
01226 /*-----------------------------------------------.
01227 | Release the memory associated to this symbol.  |
01228 `-----------------------------------------------*/
01229 
01230 /*ARGSUSED*/
01231 #if (defined __STDC__ || defined __C99__FUNC__ \
01232      || defined __cplusplus || defined _MSC_VER)
01233 static void
01234 yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
01235 #else
01236 static void
01237 yydestruct (yymsg, yytype, yyvaluep, yylocationp)
01238     const char *yymsg;
01239     int yytype;
01240     YYSTYPE *yyvaluep;
01241     YYLTYPE *yylocationp;
01242 #endif
01243 {
01244   YYUSE (yyvaluep);
01245   YYUSE (yylocationp);
01246 
01247   if (!yymsg)
01248     yymsg = "Deleting";
01249   YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
01250 
01251   switch (yytype)
01252     {
01253       case 3: /* "TOK_COLONCOLON" */
01254 #line 169 "ast_expr2.y"
01255    {  free_value((yyvaluep->val)); };
01256 #line 1257 "ast_expr2.c"
01257    break;
01258       case 4: /* "TOK_COND" */
01259 #line 169 "ast_expr2.y"
01260    {  free_value((yyvaluep->val)); };
01261 #line 1262 "ast_expr2.c"
01262    break;
01263       case 5: /* "TOK_OR" */
01264 #line 169 "ast_expr2.y"
01265    {  free_value((yyvaluep->val)); };
01266 #line 1267 "ast_expr2.c"
01267    break;
01268       case 6: /* "TOK_AND" */
01269 #line 169 "ast_expr2.y"
01270    {  free_value((yyvaluep->val)); };
01271 #line 1272 "ast_expr2.c"
01272    break;
01273       case 7: /* "TOK_NE" */
01274 #line 169 "ast_expr2.y"
01275    {  free_value((yyvaluep->val)); };
01276 #line 1277 "ast_expr2.c"
01277    break;
01278       case 8: /* "TOK_LE" */
01279 #line 169 "ast_expr2.y"
01280    {  free_value((yyvaluep->val)); };
01281 #line 1282 "ast_expr2.c"
01282    break;
01283       case 9: /* "TOK_GE" */
01284 #line 169 "ast_expr2.y"
01285    {  free_value((yyvaluep->val)); };
01286 #line 1287 "ast_expr2.c"
01287    break;
01288       case 10: /* "TOK_LT" */
01289 #line 169 "ast_expr2.y"
01290    {  free_value((yyvaluep->val)); };
01291 #line 1292 "ast_expr2.c"
01292    break;
01293       case 11: /* "TOK_GT" */
01294 #line 169 "ast_expr2.y"
01295    {  free_value((yyvaluep->val)); };
01296 #line 1297 "ast_expr2.c"
01297    break;
01298       case 12: /* "TOK_EQ" */
01299 #line 169 "ast_expr2.y"
01300    {  free_value((yyvaluep->val)); };
01301 #line 1302 "ast_expr2.c"
01302    break;
01303       case 13: /* "TOK_MINUS" */
01304 #line 169 "ast_expr2.y"
01305    {  free_value((yyvaluep->val)); };
01306 #line 1307 "ast_expr2.c"
01307    break;
01308       case 14: /* "TOK_PLUS" */
01309 #line 169 "ast_expr2.y"
01310    {  free_value((yyvaluep->val)); };
01311 #line 1312 "ast_expr2.c"
01312    break;
01313       case 15: /* "TOK_MOD" */
01314 #line 169 "ast_expr2.y"
01315    {  free_value((yyvaluep->val)); };
01316 #line 1317 "ast_expr2.c"
01317    break;
01318       case 16: /* "TOK_DIV" */
01319 #line 169 "ast_expr2.y"
01320    {  free_value((yyvaluep->val)); };
01321 #line 1322 "ast_expr2.c"
01322    break;
01323       case 17: /* "TOK_MULT" */
01324 #line 169 "ast_expr2.y"
01325    {  free_value((yyvaluep->val)); };
01326 #line 1327 "ast_expr2.c"
01327    break;
01328       case 18: /* "TOK_COMPL" */
01329 #line 169 "ast_expr2.y"
01330    {  free_value((yyvaluep->val)); };
01331 #line 1332 "ast_expr2.c"
01332    break;
01333       case 19: /* "TOK_EQTILDE" */
01334 #line 169 "ast_expr2.y"
01335    {  free_value((yyvaluep->val)); };
01336 #line 1337 "ast_expr2.c"
01337    break;
01338       case 20: /* "TOK_COLON" */
01339 #line 169 "ast_expr2.y"
01340    {  free_value((yyvaluep->val)); };
01341 #line 1342 "ast_expr2.c"
01342    break;
01343       case 21: /* "TOK_LP" */
01344 #line 169 "ast_expr2.y"
01345    {  free_value((yyvaluep->val)); };
01346 #line 1347 "ast_expr2.c"
01347    break;
01348       case 22: /* "TOK_RP" */
01349 #line 169 "ast_expr2.y"
01350    {  free_value((yyvaluep->val)); };
01351 #line 1352 "ast_expr2.c"
01352    break;
01353       case 23: /* "TOKEN" */
01354 #line 169 "ast_expr2.y"
01355    {  free_value((yyvaluep->val)); };
01356 #line 1357 "ast_expr2.c"
01357    break;
01358       case 26: /* "expr" */
01359 #line 169 "ast_expr2.y"
01360    {  free_value((yyvaluep->val)); };
01361 #line 1362 "ast_expr2.c"
01362    break;
01363 
01364       default:
01365    break;
01366     }
01367 }
01368 
01369 
01370 /* Prevent warnings from -Wmissing-prototypes.  */
01371 
01372 #ifdef YYPARSE_PARAM
01373 #if defined __STDC__ || defined __cplusplus
01374 int yyparse (void *YYPARSE_PARAM);
01375 #else
01376 int yyparse ();
01377 #endif
01378 #else /* ! YYPARSE_PARAM */
01379 #if defined __STDC__ || defined __cplusplus
01380 int yyparse (void);
01381 #else
01382 int yyparse ();
01383 #endif
01384 #endif /* ! YYPARSE_PARAM */
01385 
01386 
01387 
01388 
01389 
01390 
01391 /*----------.
01392 | yyparse.  |
01393 `----------*/
01394 
01395 #ifdef YYPARSE_PARAM
01396 #if (defined __STDC__ || defined __C99__FUNC__ \
01397      || defined __cplusplus || defined _MSC_VER)
01398 int
01399 yyparse (void *YYPARSE_PARAM)
01400 #else
01401 int
01402 yyparse (YYPARSE_PARAM)
01403     void *YYPARSE_PARAM;
01404 #endif
01405 #else /* ! YYPARSE_PARAM */
01406 #if (defined __STDC__ || defined __C99__FUNC__ \
01407      || defined __cplusplus || defined _MSC_VER)
01408 int
01409 yyparse (void)
01410 #else
01411 int
01412 yyparse ()
01413 
01414 #endif
01415 #endif
01416 {
01417   /* The look-ahead symbol.  */
01418 int yychar;
01419 
01420 /* The semantic value of the look-ahead symbol.  */
01421 YYSTYPE yylval;
01422 
01423 /* Number of syntax errors so far.  */
01424 int yynerrs;
01425 /* Location data for the look-ahead symbol.  */
01426 YYLTYPE yylloc;
01427 
01428   int yystate;
01429   int yyn;
01430   int yyresult;
01431   /* Number of tokens to shift before error messages enabled.  */
01432   int yyerrstatus;
01433   /* Look-ahead token as an internal (translated) token number.  */
01434   int yytoken = 0;
01435 #if YYERROR_VERBOSE
01436   /* Buffer for error messages, and its allocated size.  */
01437   char yymsgbuf[128];
01438   char *yymsg = yymsgbuf;
01439   YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
01440 #endif
01441 
01442   /* Three stacks and their tools:
01443      `yyss': related to states,
01444      `yyvs': related to semantic values,
01445      `yyls': related to locations.
01446 
01447      Refer to the stacks thru separate pointers, to allow yyoverflow
01448      to reallocate them elsewhere.  */
01449 
01450   /* The state stack.  */
01451   yytype_int16 yyssa[YYINITDEPTH];
01452   yytype_int16 *yyss = yyssa;
01453   yytype_int16 *yyssp;
01454 
01455   /* The semantic value stack.  */
01456   YYSTYPE yyvsa[YYINITDEPTH];
01457   YYSTYPE *yyvs = yyvsa;
01458   YYSTYPE *yyvsp;
01459 
01460   /* The location stack.  */
01461   YYLTYPE yylsa[YYINITDEPTH];
01462   YYLTYPE *yyls = yylsa;
01463   YYLTYPE *yylsp;
01464   /* The locations where the error started and ended.  */
01465   YYLTYPE yyerror_range[2];
01466 
01467 #define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
01468 
01469   YYSIZE_T yystacksize = YYINITDEPTH;
01470 
01471   /* The variables used to return semantic value and location from the
01472      action routines.  */
01473   YYSTYPE yyval;
01474   YYLTYPE yyloc;
01475 
01476   /* The number of symbols on the RHS of the reduced rule.
01477      Keep to zero when no symbol should be popped.  */
01478   int yylen = 0;
01479 
01480   YYDPRINTF ((stderr, "Starting parse\n"));
01481 
01482   yystate = 0;
01483   yyerrstatus = 0;
01484   yynerrs = 0;
01485   yychar = YYEMPTY;     /* Cause a token to be read.  */
01486 
01487   /* Initialize stack pointers.
01488      Waste one element of value and location stack
01489      so that they stay on the same level as the state stack.
01490      The wasted elements are never initialized.  */
01491 
01492   yyssp = yyss;
01493   yyvsp = yyvs;
01494   yylsp = yyls;
01495 #if YYLTYPE_IS_TRIVIAL
01496   /* Initialize the default location before parsing starts.  */
01497   yylloc.first_line   = yylloc.last_line   = 1;
01498   yylloc.first_column = yylloc.last_column = 0;
01499 #endif
01500 
01501   goto yysetstate;
01502 
01503 /*------------------------------------------------------------.
01504 | yynewstate -- Push a new state, which is found in yystate.  |
01505 `------------------------------------------------------------*/
01506  yynewstate:
01507   /* In all cases, when you get here, the value and location stacks
01508      have just been pushed.  So pushing a state here evens the stacks.  */
01509   yyssp++;
01510 
01511  yysetstate:
01512   *yyssp = yystate;
01513 
01514   if (yyss + yystacksize - 1 <= yyssp)
01515     {
01516       /* Get the current used size of the three stacks, in elements.  */
01517       YYSIZE_T yysize = yyssp - yyss + 1;
01518 
01519 #ifdef yyoverflow
01520       {
01521    /* Give user a chance to reallocate the stack.  Use copies of
01522       these so that the &'s don't force the real ones into
01523       memory.  */
01524    YYSTYPE *yyvs1 = yyvs;
01525    yytype_int16 *yyss1 = yyss;
01526    YYLTYPE *yyls1 = yyls;
01527 
01528    /* Each stack pointer address is followed by the size of the
01529       data in use in that stack, in bytes.  This used to be a
01530       conditional around just the two extra args, but that might
01531       be undefined if yyoverflow is a macro.  */
01532    yyoverflow (YY_("memory exhausted"),
01533           &yyss1, yysize * sizeof (*yyssp),
01534           &yyvs1, yysize * sizeof (*yyvsp),
01535           &yyls1, yysize * sizeof (*yylsp),
01536           &yystacksize);
01537    yyls = yyls1;
01538    yyss = yyss1;
01539    yyvs = yyvs1;
01540       }
01541 #else /* no yyoverflow */
01542 # ifndef YYSTACK_RELOCATE
01543       goto yyexhaustedlab;
01544 # else
01545       /* Extend the stack our own way.  */
01546       if (YYMAXDEPTH <= yystacksize)
01547    goto yyexhaustedlab;
01548       yystacksize *= 2;
01549       if (YYMAXDEPTH < yystacksize)
01550    yystacksize = YYMAXDEPTH;
01551 
01552       {
01553    yytype_int16 *yyss1 = yyss;
01554    union yyalloc *yyptr =
01555      (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
01556    if (! yyptr)
01557      goto yyexhaustedlab;
01558    YYSTACK_RELOCATE (yyss);
01559    YYSTACK_RELOCATE (yyvs);
01560    YYSTACK_RELOCATE (yyls);
01561 #  undef YYSTACK_RELOCATE
01562    if (yyss1 != yyssa)
01563      YYSTACK_FREE (yyss1);
01564       }
01565 # endif
01566 #endif /* no yyoverflow */
01567 
01568       yyssp = yyss + yysize - 1;
01569       yyvsp = yyvs + yysize - 1;
01570       yylsp = yyls + yysize - 1;
01571 
01572       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
01573         (unsigned long int) yystacksize));
01574 
01575       if (yyss + yystacksize - 1 <= yyssp)
01576    YYABORT;
01577     }
01578 
01579   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
01580 
01581   goto yybackup;
01582 
01583 /*-----------.
01584 | yybackup.  |
01585 `-----------*/
01586 yybackup:
01587 
01588   /* Do appropriate processing given the current state.  Read a
01589      look-ahead token if we need one and don't already have one.  */
01590 
01591   /* First try to decide what to do without reference to look-ahead token.  */
01592   yyn = yypact[yystate];
01593   if (yyn == YYPACT_NINF)
01594     goto yydefault;
01595 
01596   /* Not known => get a look-ahead token if don't already have one.  */
01597 
01598   /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
01599   if (yychar == YYEMPTY)
01600     {
01601       YYDPRINTF ((stderr, "Reading a token: "));
01602       yychar = YYLEX;
01603     }
01604 
01605   if (yychar <= YYEOF)
01606     {
01607       yychar = yytoken = YYEOF;
01608       YYDPRINTF ((stderr, "Now at end of input.\n"));
01609     }
01610   else
01611     {
01612       yytoken = YYTRANSLATE (yychar);
01613       YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
01614     }
01615 
01616   /* If the proper action on seeing token YYTOKEN is to reduce or to
01617      detect an error, take that action.  */
01618   yyn += yytoken;
01619   if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
01620     goto yydefault;
01621   yyn = yytable[yyn];
01622   if (yyn <= 0)
01623     {
01624       if (yyn == 0 || yyn == YYTABLE_NINF)
01625    goto yyerrlab;
01626       yyn = -yyn;
01627       goto yyreduce;
01628     }
01629 
01630   if (yyn == YYFINAL)
01631     YYACCEPT;
01632 
01633   /* Count tokens shifted since error; after three, turn off error
01634      status.  */
01635   if (yyerrstatus)
01636     yyerrstatus--;
01637 
01638   /* Shift the look-ahead token.  */
01639   YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
01640 
01641   /* Discard the shifted token unless it is eof.  */
01642   if (yychar != YYEOF)
01643     yychar = YYEMPTY;
01644 
01645   yystate = yyn;
01646   *++yyvsp = yylval;
01647   *++yylsp = yylloc;
01648   goto yynewstate;
01649 
01650 
01651 /*-----------------------------------------------------------.
01652 | yydefault -- do the default action for the current state.  |
01653 `-----------------------------------------------------------*/
01654 yydefault:
01655   yyn = yydefact[yystate];
01656   if (yyn == 0)
01657     goto yyerrlab;
01658   goto yyreduce;
01659 
01660 
01661 /*-----------------------------.
01662 | yyreduce -- Do a reduction.  |
01663 `-----------------------------*/
01664 yyreduce:
01665   /* yyn is the number of a rule to reduce with.  */
01666   yylen = yyr2[yyn];
01667 
01668   /* If YYLEN is nonzero, implement the default value of the action:
01669      `$$ = $1'.
01670 
01671      Otherwise, the following line sets YYVAL to garbage.
01672      This behavior is undocumented and Bison
01673      users should not rely upon it.  Assigning to YYVAL
01674      unconditionally makes the parser a bit smaller, and it avoids a
01675      GCC warning that YYVAL may be used uninitialized.  */
01676   yyval = yyvsp[1-yylen];
01677 
01678   /* Default location.  */
01679   YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
01680   YY_REDUCE_PRINT (yyn);
01681   switch (yyn)
01682     {
01683         case 2:
01684 #line 175 "ast_expr2.y"
01685     { ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1);
01686               ((struct parse_io *)parseio)->val->type = (yyvsp[(1) - (1)].val)->type;
01687               if( (yyvsp[(1) - (1)].val)->type == AST_EXPR_integer )
01688               ((struct parse_io *)parseio)->val->u.i = (yyvsp[(1) - (1)].val)->u.i;
01689               else
01690               ((struct parse_io *)parseio)->val->u.s = (yyvsp[(1) - (1)].val)->u.s; 
01691            free((yyvsp[(1) - (1)].val));
01692          ;}
01693     break;
01694 
01695   case 3:
01696 #line 183 "ast_expr2.y"
01697     {/* nothing */ ((struct parse_io *)parseio)->val = (struct val *)calloc(sizeof(struct val),1);
01698               ((struct parse_io *)parseio)->val->type = AST_EXPR_string;
01699            ((struct parse_io *)parseio)->val->u.s = strdup(""); 
01700          ;}
01701     break;
01702 
01703   case 4:
01704 #line 190 "ast_expr2.y"
01705     { (yyval.val)= (yyvsp[(1) - (1)].val);;}
01706     break;
01707 
01708   case 5:
01709 #line 191 "ast_expr2.y"
01710     { (yyval.val) = (yyvsp[(2) - (3)].val); 
01711                           (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
01712                      (yyloc).first_line=0; (yyloc).last_line=0;
01713                      DESTROY((yyvsp[(1) - (3)].val)); DESTROY((yyvsp[(3) - (3)].val)); ;}
01714     break;
01715 
01716   case 6:
01717 #line 195 "ast_expr2.y"
01718     { (yyval.val) = op_or ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
01719                   DESTROY((yyvsp[(2) - (3)].val)); 
01720                          (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
01721                    (yyloc).first_line=0; (yyloc).last_line=0;;}
01722     break;
01723 
01724   case 7:
01725 #line 199 "ast_expr2.y"
01726     { (yyval.val) = op_and ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
01727                   DESTROY((yyvsp[(2) - (3)].val)); 
01728                          (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
01729                           (yyloc).first_line=0; (yyloc).last_line=0;;}
01730     break;
01731 
01732   case 8:
01733 #line 203 "ast_expr2.y"
01734     { (yyval.val) = op_eq ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
01735                   DESTROY((yyvsp[(2) - (3)].val)); 
01736                         (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
01737                    (yyloc).first_line=0; (yyloc).last_line=0;;}
01738     break;
01739 
01740   case 9:
01741 #line 207 "ast_expr2.y"
01742     { (yyval.val) = op_gt ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val));
01743                   DESTROY((yyvsp[(2) - (3)].val)); 
01744                          (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column;
01745                    (yyloc).first_line=0; (yyloc).last_line=0;;}
01746     break;
01747 
01748   case 10:
01749 #line 211 "ast_expr2.y"
01750     { (yyval.val) = op_lt ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
01751                   DESTROY((yyvsp[(2) - (3)].val)); 
01752                         (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
01753                    (yyloc).first_line=0; (yyloc).last_line=0;;}
01754     break;
01755 
01756   case 11:
01757 #line 215 "ast_expr2.y"
01758     { (yyval.val) = op_ge ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
01759                   DESTROY((yyvsp[(2) - (3)].val)); 
01760                          (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
01761                     (yyloc).first_line=0; (yyloc).last_line=0;;}
01762     break;
01763 
01764   case 12:
01765 #line 219 "ast_expr2.y"
01766     { (yyval.val) = op_le ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
01767                   DESTROY((yyvsp[(2) - (3)].val)); 
01768                          (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
01769                     (yyloc).first_line=0; (yyloc).last_line=0;;}
01770     break;
01771 
01772   case 13:
01773 #line 223 "ast_expr2.y"
01774     { (yyval.val) = op_ne ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
01775                   DESTROY((yyvsp[(2) - (3)].val)); 
01776                          (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
01777                     (yyloc).first_line=0; (yyloc).last_line=0;;}
01778     break;
01779 
01780   case 14:
01781 #line 227 "ast_expr2.y"
01782     { (yyval.val) = op_plus ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
01783                   DESTROY((yyvsp[(2) - (3)].val)); 
01784                           (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
01785                      (yyloc).first_line=0; (yyloc).last_line=0;;}
01786     break;
01787 
01788   case 15:
01789 #line 231 "ast_expr2.y"
01790     { (yyval.val) = op_minus ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
01791                   DESTROY((yyvsp[(2) - (3)].val)); 
01792                            (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
01793                      (yyloc).first_line=0; (yyloc).last_line=0;;}
01794     break;
01795 
01796   case 16:
01797 #line 235 "ast_expr2.y"
01798     { (yyval.val) = op_negate ((yyvsp[(2) - (2)].val)); 
01799                   DESTROY((yyvsp[(1) - (2)].val)); 
01800                            (yyloc).first_column = (yylsp[(1) - (2)]).first_column; (yyloc).last_column = (yylsp[(2) - (2)]).last_column; 
01801                      (yyloc).first_line=0; (yyloc).last_line=0;;}
01802     break;
01803 
01804   case 17:
01805 #line 239 "ast_expr2.y"
01806     { (yyval.val) = op_compl ((yyvsp[(2) - (2)].val)); 
01807                   DESTROY((yyvsp[(1) - (2)].val)); 
01808                            (yyloc).first_column = (yylsp[(1) - (2)]).first_column; (yyloc).last_column = (yylsp[(2) - (2)]).last_column; 
01809                      (yyloc).first_line=0; (yyloc).last_line=0;;}
01810     break;
01811 
01812   case 18:
01813 #line 243 "ast_expr2.y"
01814     { (yyval.val) = op_times ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
01815                   DESTROY((yyvsp[(2) - (3)].val)); 
01816                           (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
01817                      (yyloc).first_line=0; (yyloc).last_line=0;;}
01818     break;
01819 
01820   case 19:
01821 #line 247 "ast_expr2.y"
01822     { (yyval.val) = op_div ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
01823                   DESTROY((yyvsp[(2) - (3)].val)); 
01824                          (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
01825                     (yyloc).first_line=0; (yyloc).last_line=0;;}
01826     break;
01827 
01828   case 20:
01829 #line 251 "ast_expr2.y"
01830     { (yyval.val) = op_rem ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
01831                   DESTROY((yyvsp[(2) - (3)].val)); 
01832                          (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
01833                     (yyloc).first_line=0; (yyloc).last_line=0;;}
01834     break;
01835 
01836   case 21:
01837 #line 255 "ast_expr2.y"
01838     { (yyval.val) = op_colon ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
01839                   DESTROY((yyvsp[(2) - (3)].val)); 
01840                            (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
01841                      (yyloc).first_line=0; (yyloc).last_line=0;;}
01842     break;
01843 
01844   case 22:
01845 #line 259 "ast_expr2.y"
01846     { (yyval.val) = op_eqtilde ((yyvsp[(1) - (3)].val), (yyvsp[(3) - (3)].val)); 
01847                   DESTROY((yyvsp[(2) - (3)].val)); 
01848                            (yyloc).first_column = (yylsp[(1) - (3)]).first_column; (yyloc).last_column = (yylsp[(3) - (3)]).last_column; 
01849                      (yyloc).first_line=0; (yyloc).last_line=0;;}
01850     break;
01851 
01852   case 23:
01853 #line 263 "ast_expr2.y"
01854     { (yyval.val) = op_cond ((yyvsp[(1) - (5)].val), (yyvsp[(3) - (5)].val), (yyvsp[(5) - (5)].val)); 
01855                   DESTROY((yyvsp[(2) - (5)].val)); 
01856                   DESTROY((yyvsp[(4) - (5)].val)); 
01857                            (yyloc).first_column = (yylsp[(1) - (5)]).first_column; (yyloc).last_column = (yylsp[(3) - (5)]).last_column; 
01858                      (yyloc).first_line=0; (yyloc).last_line=0;;}
01859     break;
01860 
01861 
01862 /* Line 1270 of yacc.c.  */
01863 #line 1864 "ast_expr2.c"
01864       default: break;
01865     }
01866   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
01867 
01868   YYPOPSTACK (yylen);
01869   yylen = 0;
01870   YY_STACK_PRINT (yyss, yyssp);
01871 
01872   *++yyvsp = yyval;
01873   *++yylsp = yyloc;
01874 
01875   /* Now `shift' the result of the reduction.  Determine what state
01876      that goes to, based on the state we popped back to and the rule
01877      number reduced by.  */
01878 
01879   yyn = yyr1[yyn];
01880 
01881   yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
01882   if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
01883     yystate = yytable[yystate];
01884   else
01885     yystate = yydefgoto[yyn - YYNTOKENS];
01886 
01887   goto yynewstate;
01888 
01889 
01890 /*------------------------------------.
01891 | yyerrlab -- here on detecting error |
01892 `------------------------------------*/
01893 yyerrlab:
01894   /* If not already recovering from an error, report this error.  */
01895   if (!yyerrstatus)
01896     {
01897       ++yynerrs;
01898 #if ! YYERROR_VERBOSE
01899       yyerror (YY_("syntax error"));
01900 #else
01901       {
01902    YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
01903    if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
01904      {
01905        YYSIZE_T yyalloc = 2 * yysize;
01906        if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
01907          yyalloc = YYSTACK_ALLOC_MAXIMUM;
01908        if (yymsg != yymsgbuf)
01909          YYSTACK_FREE (yymsg);
01910        yymsg = (char *) YYSTACK_ALLOC (yyalloc);
01911        if (yymsg)
01912          yymsg_alloc = yyalloc;
01913        else
01914          {
01915       yymsg = yymsgbuf;
01916       yymsg_alloc = sizeof yymsgbuf;
01917          }
01918      }
01919 
01920    if (0 < yysize && yysize <= yymsg_alloc)
01921      {
01922        (void) yysyntax_error (yymsg, yystate, yychar);
01923        yyerror (yymsg);
01924      }
01925    else
01926      {
01927        yyerror (YY_("syntax error"));
01928        if (yysize != 0)
01929          goto yyexhaustedlab;
01930      }
01931       }
01932 #endif
01933     }
01934 
01935   yyerror_range[0] = yylloc;
01936 
01937   if (yyerrstatus == 3)
01938     {
01939       /* If just tried and failed to reuse look-ahead token after an
01940     error, discard it.  */
01941 
01942       if (yychar <= YYEOF)
01943    {
01944      /* Return failure if at end of input.  */
01945      if (yychar == YYEOF)
01946        YYABORT;
01947    }
01948       else
01949    {
01950      yydestruct ("Error: discarding",
01951             yytoken, &yylval, &yylloc);
01952      yychar = YYEMPTY;
01953    }
01954     }
01955 
01956   /* Else will try to reuse look-ahead token after shifting the error
01957      token.  */
01958   goto yyerrlab1;
01959 
01960 
01961 /*---------------------------------------------------.
01962 | yyerrorlab -- error raised explicitly by YYERROR.  |
01963 `---------------------------------------------------*/
01964 yyerrorlab:
01965 
01966   /* Pacify compilers like GCC when the user code never invokes
01967      YYERROR and the label yyerrorlab therefore never appears in user
01968      code.  */
01969   if (/*CONSTCOND*/ 0)
01970      goto yyerrorlab;
01971 
01972   yyerror_range[0] = yylsp[1-yylen];
01973   /* Do not reclaim the symbols of the rule which action triggered
01974      this YYERROR.  */
01975   YYPOPSTACK (yylen);
01976   yylen = 0;
01977   YY_STACK_PRINT (yyss, yyssp);
01978   yystate = *yyssp;
01979   goto yyerrlab1;
01980 
01981 
01982 /*-------------------------------------------------------------.
01983 | yyerrlab1 -- common code for both syntax error and YYERROR.  |
01984 `-------------------------------------------------------------*/
01985 yyerrlab1:
01986   yyerrstatus = 3;   /* Each real token shifted decrements this.  */
01987 
01988   for (;;)
01989     {
01990       yyn = yypact[yystate];
01991       if (yyn != YYPACT_NINF)
01992    {
01993      yyn += YYTERROR;
01994      if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
01995        {
01996          yyn = yytable[yyn];
01997          if (0 < yyn)
01998       break;
01999        }
02000    }
02001 
02002       /* Pop the current state because it cannot handle the error token.  */
02003       if (yyssp == yyss)
02004    YYABORT;
02005 
02006       yyerror_range[0] = *yylsp;
02007       yydestruct ("Error: popping",
02008         yystos[yystate], yyvsp, yylsp);
02009       YYPOPSTACK (1);
02010       yystate = *yyssp;
02011       YY_STACK_PRINT (yyss, yyssp);
02012     }
02013 
02014   if (yyn == YYFINAL)
02015     YYACCEPT;
02016 
02017   *++yyvsp = yylval;
02018 
02019   yyerror_range[1] = yylloc;
02020   /* Using YYLLOC is tempting, but would change the location of
02021      the look-ahead.  YYLOC is available though.  */
02022   YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
02023   *++yylsp = yyloc;
02024 
02025   /* Shift the error token.  */
02026   YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
02027 
02028   yystate = yyn;
02029   goto yynewstate;
02030 
02031 
02032 /*-------------------------------------.
02033 | yyacceptlab -- YYACCEPT comes here.  |
02034 `-------------------------------------*/
02035 yyacceptlab:
02036   yyresult = 0;
02037   goto yyreturn;
02038 
02039 /*-----------------------------------.
02040 | yyabortlab -- YYABORT comes here.  |
02041 `-----------------------------------*/
02042 yyabortlab:
02043   yyresult = 1;
02044   goto yyreturn;
02045 
02046 #ifndef yyoverflow
02047 /*-------------------------------------------------.
02048 | yyexhaustedlab -- memory exhaustion comes here.  |
02049 `-------------------------------------------------*/
02050 yyexhaustedlab:
02051   yyerror (YY_("memory exhausted"));
02052   yyresult = 2;
02053   /* Fall through.  */
02054 #endif
02055 
02056 yyreturn:
02057   if (yychar != YYEOF && yychar != YYEMPTY)
02058      yydestruct ("Cleanup: discarding lookahead",
02059        yytoken, &yylval, &yylloc);
02060   /* Do not reclaim the symbols of the rule which action triggered
02061      this YYABORT or YYACCEPT.  */
02062   YYPOPSTACK (yylen);
02063   YY_STACK_PRINT (yyss, yyssp);
02064   while (yyssp != yyss)
02065     {
02066       yydestruct ("Cleanup: popping",
02067         yystos[*yyssp], yyvsp, yylsp);
02068       YYPOPSTACK (1);
02069     }
02070 #ifndef yyoverflow
02071   if (yyss != yyssa)
02072     YYSTACK_FREE (yyss);
02073 #endif
02074 #if YYERROR_VERBOSE
02075   if (yymsg != yymsgbuf)
02076     YYSTACK_FREE (yymsg);
02077 #endif
02078   return yyresult;
02079 }
02080 
02081 
02082 #line 270 "ast_expr2.y"
02083 
02084 
02085 static struct val *
02086 make_integer (quad_t i)
02087 {
02088    struct val *vp;
02089 
02090    vp = (struct val *) malloc (sizeof (*vp));
02091    if (vp == NULL) {
02092       ast_log(LOG_WARNING, "malloc() failed\n");
02093       return(NULL);
02094    }
02095 
02096    vp->type = AST_EXPR_integer;
02097    vp->u.i  = i;
02098    return vp; 
02099 }
02100 
02101 static struct val *
02102 make_str (const char *s)
02103 {
02104    struct val *vp;
02105    size_t i;
02106    int isint;
02107 
02108    vp = (struct val *) malloc (sizeof (*vp));
02109    if (vp == NULL || ((vp->u.s = strdup (s)) == NULL)) {
02110       ast_log(LOG_WARNING,"malloc() failed\n");
02111       return(NULL);
02112    }
02113 
02114    for(i = 1, isint = isdigit(s[0]) || s[0] == '-';
02115        isint && i < strlen(s);
02116        i++)
02117    {
02118       if(!isdigit(s[i]))
02119           isint = 0;
02120    }
02121 
02122    if (isint)
02123       vp->type = AST_EXPR_numeric_string;
02124    else  
02125       vp->type = AST_EXPR_string;
02126 
02127    return vp;
02128 }
02129 
02130 
02131 static void
02132 free_value (struct val *vp)
02133 {  
02134    if (vp==NULL) {
02135       return;
02136    }
02137    if (vp->type == AST_EXPR_string || vp->type == AST_EXPR_numeric_string)
02138       free (vp->u.s);   
02139    free(vp);
02140 }
02141 
02142 
02143 static quad_t
02144 to_integer (struct val *vp)
02145 {
02146    quad_t i;
02147    
02148    if (vp == NULL) {
02149       ast_log(LOG_WARNING,"vp==NULL in to_integer()\n");
02150       return(0);
02151    }
02152 
02153    if (vp->type == AST_EXPR_integer)
02154       return 1;
02155 
02156    if (vp->type == AST_EXPR_string)
02157       return 0;
02158 
02159    /* vp->type == AST_EXPR_numeric_string, make it numeric */
02160    errno = 0;
02161    i  = strtoll(vp->u.s, (char**)NULL, 10);
02162    if (errno != 0) {
02163       ast_log(LOG_WARNING,"Conversion of %s to integer under/overflowed!\n", vp->u.s);
02164       free(vp->u.s);
02165       vp->u.s = 0;
02166       return(0);
02167    }
02168    free (vp->u.s);
02169    vp->u.i = i;
02170    vp->type = AST_EXPR_integer;
02171    return 1;
02172 }
02173 
02174 static void
02175 strip_quotes(struct val *vp)
02176 {
02177    if (vp->type != AST_EXPR_string && vp->type != AST_EXPR_numeric_string)
02178       return;
02179    
02180    if( vp->u.s[0] == '"' && vp->u.s[strlen(vp->u.s)-1] == '"' )
02181    {
02182       char *f, *t;
02183       f = vp->u.s;
02184       t = vp->u.s;
02185       
02186       while( *f )
02187       {
02188          if( *f  && *f != '"' )
02189             *t++ = *f++;
02190          else
02191             f++;
02192       }
02193       *t = *f;
02194    }
02195 }
02196 
02197 static void
02198 to_string (struct val *vp)
02199 {
02200    char *tmp;
02201 
02202    if (vp->type == AST_EXPR_string || vp->type == AST_EXPR_numeric_string)
02203       return;
02204 
02205    tmp = malloc ((size_t)25);
02206    if (tmp == NULL) {
02207       ast_log(LOG_WARNING,"malloc() failed\n");
02208       return;
02209    }
02210 
02211    sprintf(tmp, "%ld", (long int) vp->u.i);
02212    vp->type = AST_EXPR_string;
02213    vp->u.s  = tmp;
02214 }
02215 
02216 
02217 static int
02218 isstring (struct val *vp)
02219 {
02220    /* only TRUE if this string is not a valid integer */
02221    return (vp->type == AST_EXPR_string);
02222 }
02223 
02224 
02225 static int
02226 is_zero_or_null (struct val *vp)
02227 {
02228    if (vp->type == AST_EXPR_integer) {
02229       return (vp->u.i == 0);
02230    } else {
02231       return (*vp->u.s == 0 || (to_integer (vp) && vp->u.i == 0));
02232    }
02233    /* NOTREACHED */
02234 }
02235 
02236 #ifdef STANDALONE
02237 
02238 void ast_log(int level, const char *file, int line, const char *function, const char *fmt, ...)
02239 {
02240    va_list vars;
02241    va_start(vars,fmt);
02242    
02243         printf("LOG: lev:%d file:%s  line:%d func: %s  ",
02244                    level, file, line, function);
02245    vprintf(fmt, vars);
02246    fflush(stdout);
02247    va_end(vars);
02248 }
02249 
02250 
02251 int main(int argc,char **argv) {
02252    char s[4096];
02253    char out[4096];
02254    FILE *infile;
02255    
02256    if( !argv[1] )
02257       exit(20);
02258    
02259    if( access(argv[1],F_OK)== 0 )
02260    {
02261       int ret;
02262       
02263       infile = fopen(argv[1],"r");
02264       if( !infile )
02265       {
02266          printf("Sorry, couldn't open %s for reading!\n", argv[1]);
02267          exit(10);
02268       }
02269       while( fgets(s,sizeof(s),infile) )
02270       {
02271          if( s[strlen(s)-1] == '\n' )
02272             s[strlen(s)-1] = 0;
02273          
02274          ret = ast_expr(s, out, sizeof(out));
02275          printf("Expression: %s    Result: [%d] '%s'\n",
02276                s, ret, out);
02277       }
02278       fclose(infile);
02279    }
02280    else
02281    {
02282       if (ast_expr(argv[1], s, sizeof(s)))
02283          printf("=====%s======\n",s);
02284       else
02285          printf("No result\n");
02286    }
02287 }
02288 
02289 #endif
02290 
02291 #undef ast_yyerror
02292 #define ast_yyerror(x) ast_yyerror(x, YYLTYPE *yylloc, struct parse_io *parseio)
02293 
02294 /* I put the ast_yyerror func in the flex input file,
02295    because it refers to the buffer state. Best to
02296    let it access the BUFFER stuff there and not trying
02297    define all the structs, macros etc. in this file! */
02298 
02299 
02300 static struct val *
02301 op_or (struct val *a, struct val *b)
02302 {
02303    if (is_zero_or_null (a)) {
02304       free_value (a);
02305       return (b);
02306    } else {
02307       free_value (b);
02308       return (a);
02309    }
02310 }
02311       
02312 static struct val *
02313 op_and (struct val *a, struct val *b)
02314 {
02315    if (is_zero_or_null (a) || is_zero_or_null (b)) {
02316       free_value (a);
02317       free_value (b);
02318       return (make_integer ((quad_t)0));
02319    } else {
02320       free_value (b);
02321       return (a);
02322    }
02323 }
02324 
02325 static struct val *
02326 op_eq (struct val *a, struct val *b)
02327 {
02328    struct val *r; 
02329 
02330    if (isstring (a) || isstring (b)) {
02331       to_string (a);
02332       to_string (b); 
02333       r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) == 0));
02334    } else {
02335 #ifdef DEBUG_FOR_CONVERSIONS
02336       char buffer[2000];
02337       sprintf(buffer,"Converting '%s' and '%s' ", a->u.s, b->u.s);
02338 #endif
02339       (void)to_integer(a);
02340       (void)to_integer(b);
02341 #ifdef DEBUG_FOR_CONVERSIONS
02342       ast_log(LOG_WARNING,"%s to '%lld' and '%lld'\n", buffer, a->u.i, b->u.i);
02343 #endif
02344       r = make_integer ((quad_t)(a->u.i == b->u.i));
02345    }
02346 
02347    free_value (a);
02348    free_value (b);
02349    return r;
02350 }
02351 
02352 static struct val *
02353 op_gt (struct val *a, struct val *b)
02354 {
02355    struct val *r;
02356 
02357    if (isstring (a) || isstring (b)) {
02358       to_string (a);
02359       to_string (b);
02360       r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) > 0));
02361    } else {
02362       (void)to_integer(a);
02363       (void)to_integer(b);
02364       r = make_integer ((quad_t)(a->u.i > b->u.i));
02365    }
02366 
02367    free_value (a);
02368    free_value (b);
02369    return r;
02370 }
02371 
02372 static struct val *
02373 op_lt (struct val *a, struct val *b)
02374 {
02375    struct val *r;
02376 
02377    if (isstring (a) || isstring (b)) {
02378       to_string (a);
02379       to_string (b);
02380       r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) < 0));
02381    } else {
02382       (void)to_integer(a);
02383       (void)to_integer(b);
02384       r = make_integer ((quad_t)(a->u.i < b->u.i));
02385    }
02386 
02387    free_value (a);
02388    free_value (b);
02389    return r;
02390 }
02391 
02392 static struct val *
02393 op_ge (struct val *a, struct val *b)
02394 {
02395    struct val *r;
02396 
02397    if (isstring (a) || isstring (b)) {
02398       to_string (a);
02399       to_string (b);
02400       r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) >= 0));
02401    } else {
02402       (void)to_integer(a);
02403       (void)to_integer(b);
02404       r = make_integer ((quad_t)(a->u.i >= b->u.i));
02405    }
02406 
02407    free_value (a);
02408    free_value (b);
02409    return r;
02410 }
02411 
02412 static struct val *
02413 op_le (struct val *a, struct val *b)
02414 {
02415    struct val *r;
02416 
02417    if (isstring (a) || isstring (b)) {
02418       to_string (a);
02419       to_string (b);
02420       r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) <= 0));
02421    } else {
02422       (void)to_integer(a);
02423       (void)to_integer(b);
02424       r = make_integer ((quad_t)(a->u.i <= b->u.i));
02425    }
02426 
02427    free_value (a);
02428    free_value (b);
02429    return r;
02430 }
02431 
02432 static struct val *
02433 op_cond (struct val *a, struct val *b, struct val *c)
02434 {
02435    struct val *r;
02436 
02437    if( isstring(a) )
02438    {
02439       if( strlen(a->u.s) && strcmp(a->u.s, "\"\"") != 0 && strcmp(a->u.s,"0") != 0 )
02440       {
02441          free_value(a);
02442          free_value(c);
02443          r = b;
02444       }
02445       else
02446       {
02447          free_value(a);
02448          free_value(b);
02449          r = c;
02450       }
02451    }
02452    else
02453    {
02454       (void)to_integer(a);
02455       if( a->u.i )
02456       {
02457          free_value(a);
02458          free_value(c);
02459          r = b;
02460       }
02461       else
02462       {
02463          free_value(a);
02464          free_value(b);
02465          r = c;
02466       }
02467    }
02468    return r;
02469 }
02470 
02471 static struct val *
02472 op_ne (struct val *a, struct val *b)
02473 {
02474    struct val *r;
02475 
02476    if (isstring (a) || isstring (b)) {
02477       to_string (a);
02478       to_string (b);
02479       r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) != 0));
02480    } else {
02481       (void)to_integer(a);
02482       (void)to_integer(b);
02483       r = make_integer ((quad_t)(a->u.i != b->u.i));
02484    }
02485 
02486    free_value (a);
02487    free_value (b);
02488    return r;
02489 }
02490 
02491 static int
02492 chk_plus (quad_t a, quad_t b, quad_t r)
02493 {
02494    /* sum of two positive numbers must be positive */
02495    if (a > 0 && b > 0 && r <= 0)
02496       return 1;
02497    /* sum of two negative numbers must be negative */
02498    if (a < 0 && b < 0 && r >= 0)
02499       return 1;
02500    /* all other cases are OK */
02501    return 0;
02502 }
02503 
02504 static struct val *
02505 op_plus (struct val *a, struct val *b)
02506 {
02507    struct val *r;
02508 
02509    if (!to_integer (a)) {
02510       if( !extra_error_message_supplied )
02511          ast_log(LOG_WARNING,"non-numeric argument\n");
02512       if (!to_integer (b)) {
02513          free_value(a);
02514          free_value(b);
02515          return make_integer(0);
02516       } else {
02517          free_value(a);
02518          return (b);
02519       }
02520    } else if (!to_integer(b)) {
02521       free_value(b);
02522       return (a);
02523    }
02524 
02525    r = make_integer (/*(quad_t)*/(a->u.i + b->u.i));
02526    if (chk_plus (a->u.i, b->u.i, r->u.i)) {
02527       ast_log(LOG_WARNING,"overflow\n");
02528    }
02529    free_value (a);
02530    free_value (b);
02531    return r;
02532 }
02533 
02534 static int
02535 chk_minus (quad_t a, quad_t b, quad_t r)
02536 {
02537    /* special case subtraction of QUAD_MIN */
02538    if (b == QUAD_MIN) {
02539       if (a >= 0)
02540          return 1;
02541       else
02542          return 0;
02543    }
02544    /* this is allowed for b != QUAD_MIN */
02545    return chk_plus (a, -b, r);
02546 }
02547 
02548 static struct val *
02549 op_minus (struct val *a, struct val *b)
02550 {
02551    struct val *r;
02552 
02553    if (!to_integer (a)) {
02554       if( !extra_error_message_supplied )
02555          ast_log(LOG_WARNING, "non-numeric argument\n");
02556       if (!to_integer (b)) {
02557          free_value(a);
02558          free_value(b);
02559          return make_integer(0);
02560       } else {
02561          r = make_integer(0 - b->u.i);
02562          free_value(a);
02563          free_value(b);
02564          return (r);
02565       }
02566    } else if (!to_integer(b)) {
02567       if( !extra_error_message_supplied )
02568          ast_log(LOG_WARNING, "non-numeric argument\n");
02569       free_value(b);
02570       return (a);
02571    }
02572 
02573    r = make_integer (/*(quad_t)*/(a->u.i - b->u.i));
02574    if (chk_minus (a->u.i, b->u.i, r->u.i)) {
02575       ast_log(LOG_WARNING, "overflow\n");
02576    }
02577    free_value (a);
02578    free_value (b);
02579    return r;
02580 }
02581 
02582 static struct val *
02583 op_negate (struct val *a)
02584 {
02585    struct val *r;
02586 
02587    if (!to_integer (a) ) {
02588       free_value(a);
02589       if( !extra_error_message_supplied )
02590          ast_log(LOG_WARNING, "non-numeric argument\n");
02591       return make_integer(0);
02592    }
02593 
02594    r = make_integer (/*(quad_t)*/(- a->u.i));
02595    if (chk_minus (0, a->u.i, r->u.i)) {
02596       ast_log(LOG_WARNING, "overflow\n");
02597    }
02598    free_value (a);
02599    return r;
02600 }
02601 
02602 static struct val *
02603 op_compl (struct val *a)
02604 {
02605    int v1 = 1;
02606    struct val *r;
02607    
02608    if( !a )
02609    {
02610       v1 = 0;
02611    }
02612    else
02613    {
02614       switch( a->type )
02615       {
02616       case AST_EXPR_integer:
02617          if( a->u.i == 0 )
02618             v1 = 0;
02619          break;
02620          
02621       case AST_EXPR_string:
02622          if( a->u.s == 0 )
02623             v1 = 0;
02624          else
02625          {
02626             if( a->u.s[0] == 0 )
02627                v1 = 0;
02628             else if (strlen(a->u.s) == 1 && a->u.s[0] == '0' )
02629                v1 = 0;
02630          }
02631          break;
02632          
02633       case AST_EXPR_numeric_string:
02634          if( a->u.s == 0 )
02635             v1 = 0;
02636          else
02637          {
02638             if( a->u.s[0] == 0 )
02639                v1 = 0;
02640             else if (strlen(a->u.s) == 1 && a->u.s[0] == '0' )
02641                v1 = 0;
02642          }
02643          break;
02644       }
02645    }
02646    
02647    r = make_integer (!v1);
02648    free_value (a);
02649    return r;
02650 }
02651 
02652 static int
02653 chk_times (quad_t a, quad_t b, quad_t r)
02654 {
02655    /* special case: first operand is 0, no overflow possible */
02656    if (a == 0)
02657       return 0;
02658    /* cerify that result of division matches second operand */
02659    if (r / a != b)
02660       return 1;
02661    return 0;
02662 }
02663 
02664 static struct val *
02665 op_times (struct val *a, struct val *b)
02666 {
02667    struct val *r;
02668 
02669    if (!to_integer (a) || !to_integer (b)) {
02670       free_value(a);
02671       free_value(b);
02672       if( !extra_error_message_supplied )
02673          ast_log(LOG_WARNING, "non-numeric argument\n");
02674       return(make_integer(0));
02675    }
02676 
02677    r = make_integer (/*(quad_t)*/(a->u.i * b->u.i));
02678    if (chk_times (a->u.i, b->u.i, r->u.i)) {
02679       ast_log(LOG_WARNING, "overflow\n");
02680    }
02681    free_value (a);
02682    free_value (b);
02683    return (r);
02684 }
02685 
02686 static int
02687 chk_div (quad_t a, quad_t b)
02688 {
02689    /* div by zero has been taken care of before */
02690    /* only QUAD_MIN / -1 causes overflow */
02691    if (a == QUAD_MIN && b == -1)
02692       return 1;
02693    /* everything else is OK */
02694    return 0;
02695 }
02696 
02697 static struct val *
02698 op_div (struct val *a, struct val *b)
02699 {
02700    struct val *r;
02701 
02702    if (!to_integer (a)) {
02703       free_value(a);
02704       free_value(b);
02705       if( !extra_error_message_supplied )
02706          ast_log(LOG_WARNING, "non-numeric argument\n");
02707       return make_integer(0);
02708    } else if (!to_integer (b)) {
02709       free_value(a);
02710       free_value(b);
02711       if( !extra_error_message_supplied )
02712          ast_log(LOG_WARNING, "non-numeric argument\n");
02713       return make_integer(INT_MAX);
02714    }
02715 
02716    if (b->u.i == 0) {
02717       ast_log(LOG_WARNING, "division by zero\n");     
02718       free_value(a);
02719       free_value(b);
02720       return make_integer(INT_MAX);
02721    }
02722 
02723    r = make_integer (/*(quad_t)*/(a->u.i / b->u.i));
02724    if (chk_div (a->u.i, b->u.i)) {
02725       ast_log(LOG_WARNING, "overflow\n");
02726    }
02727    free_value (a);
02728    free_value (b);
02729    return r;
02730 }
02731    
02732 static struct val *
02733 op_rem (struct val *a, struct val *b)
02734 {
02735    struct val *r;
02736 
02737    if (!to_integer (a) || !to_integer (b)) {
02738       if( !extra_error_message_supplied )
02739          ast_log(LOG_WARNING, "non-numeric argument\n");
02740       free_value(a);
02741       free_value(b);
02742       return make_integer(0);
02743    }
02744 
02745    if (b->u.i == 0) {
02746       ast_log(LOG_WARNING, "div by zero\n");
02747       free_value(a);
02748       return(b);
02749    }
02750 
02751    r = make_integer (/*(quad_t)*/(a->u.i % b->u.i));
02752    /* chk_rem necessary ??? */
02753    free_value (a);
02754    free_value (b);
02755    return r;
02756 }
02757    
02758 
02759 static struct val *
02760 op_colon (struct val *a, struct val *b)
02761 {
02762    regex_t rp;
02763    regmatch_t rm[2];
02764    char errbuf[256];
02765    int eval;
02766    struct val *v;
02767 
02768    /* coerce to both arguments to strings */
02769    to_string(a);
02770    to_string(b);
02771    /* strip double quotes from both -- they'll screw up the pattern, and the search string starting at ^ */
02772    strip_quotes(a);
02773    strip_quotes(b);
02774    /* compile regular expression */
02775    if ((eval = regcomp (&rp, b->u.s, REG_EXTENDED)) != 0) {
02776       regerror (eval, &rp, errbuf, sizeof(errbuf));
02777       ast_log(LOG_WARNING,"regcomp() error : %s",errbuf);
02778       free_value(a);
02779       free_value(b);
02780       return make_str("");    
02781    }
02782 
02783    /* compare string against pattern */
02784    /* remember that patterns are anchored to the beginning of the line */
02785    if (regexec(&rp, a->u.s, (size_t)2, rm, 0) == 0 && rm[0].rm_so == 0) {
02786       if (rm[1].rm_so >= 0) {
02787          *(a->u.s + rm[1].rm_eo) = '\0';
02788          v = make_str (a->u.s + rm[1].rm_so);
02789 
02790       } else {
02791          v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so));
02792       }
02793    } else {
02794       if (rp.re_nsub == 0) {
02795          v = make_integer ((quad_t)0);
02796       } else {
02797          v = make_str ("");
02798       }
02799    }
02800 
02801    /* free arguments and pattern buffer */
02802    free_value (a);
02803    free_value (b);
02804    regfree (&rp);
02805 
02806    return v;
02807 }
02808    
02809 
02810 static struct val *
02811 op_eqtilde (struct val *a, struct val *b)
02812 {
02813    regex_t rp;
02814    regmatch_t rm[2];
02815    char errbuf[256];
02816    int eval;
02817    struct val *v;
02818 
02819    /* coerce to both arguments to strings */
02820    to_string(a);
02821    to_string(b);
02822    /* strip double quotes from both -- they'll screw up the pattern, and the search string starting at ^ */
02823    strip_quotes(a);
02824    strip_quotes(b);
02825    /* compile regular expression */
02826    if ((eval = regcomp (&rp, b->u.s, REG_EXTENDED)) != 0) {
02827       regerror (eval, &rp, errbuf, sizeof(errbuf));
02828       ast_log(LOG_WARNING,"regcomp() error : %s",errbuf);
02829       free_value(a);
02830       free_value(b);
02831       return make_str("");    
02832    }
02833 
02834    /* compare string against pattern */
02835    /* remember that patterns are anchored to the beginning of the line */
02836    if (regexec(&rp, a->u.s, (size_t)2, rm, 0) == 0 ) {
02837       if (rm[1].rm_so >= 0) {
02838          *(a->u.s + rm[1].rm_eo) = '\0';
02839          v = make_str (a->u.s + rm[1].rm_so);
02840 
02841       } else {
02842          v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so));
02843       }
02844    } else {
02845       if (rp.re_nsub == 0) {
02846          v = make_integer ((quad_t)0);
02847       } else {
02848          v = make_str ("");
02849       }
02850    }
02851 
02852    /* free arguments and pattern buffer */
02853    free_value (a);
02854    free_value (b);
02855    regfree (&rp);
02856 
02857    return v;
02858 }
02859 

Generated on Sat Jul 26 06:12:58 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1