Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

ast_expr.c

Go to the documentation of this file.
00001 /* A Bison parser, made by GNU Bison 2.0.  */
00002 
00003 /* Skeleton parser for Yacc-like parsing with Bison,
00004    Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 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., 59 Temple Place - Suite 330,
00019    Boston, MA 02111-1307, 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 /* Written by Richard Stallman by simplifying the original so called
00027    ``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 /* Skeleton name.  */
00040 #define YYSKELETON_NAME "yacc.c"
00041 
00042 /* Pure parsers.  */
00043 #define YYPURE 1
00044 
00045 /* Using locations.  */
00046 #define YYLSP_NEEDED 1
00047 
00048 /* Substitute the variable and function names.  */
00049 #define yyparse ast_yyparse
00050 #define yylex   ast_yylex
00051 #define yyerror ast_yyerror
00052 #define yylval  ast_yylval
00053 #define yychar  ast_yychar
00054 #define yydebug ast_yydebug
00055 #define yynerrs ast_yynerrs
00056 #define yylloc ast_yylloc
00057 
00058 /* Tokens.  */
00059 #ifndef YYTOKENTYPE
00060 # define YYTOKENTYPE
00061    /* Put the tokens into the symbol table, so that GDB and other debuggers
00062       know about them.  */
00063    enum yytokentype {
00064      NE = 258,
00065      LE = 259,
00066      GE = 260,
00067      TOKEN = 261
00068    };
00069 #endif
00070 #define NE 258
00071 #define LE 259
00072 #define GE 260
00073 #define TOKEN 261
00074 
00075 
00076 
00077 
00078 /* Copy the first part of user declarations.  */
00079 #line 1 "ast_expr.y"
00080 
00081 /* Written by Pace Willisson (pace@blitz.com) 
00082  * and placed in the public domain.
00083  *
00084  * Largely rewritten by J.T. Conklin (jtc@wimsey.com)
00085  *
00086  * $FreeBSD: src/bin/expr/expr.y,v 1.16 2000/07/22 10:59:36 se Exp $
00087  */
00088 
00089 #include <sys/types.h>
00090 #include <stdio.h>
00091 #include <stdlib.h>
00092 #include <string.h>
00093 #include <locale.h>
00094 #include <ctype.h>
00095 #include <err.h>
00096 #include <errno.h>
00097 #include <regex.h>
00098 #include <limits.h>
00099 #include <asterisk/ast_expr.h>
00100 #include <asterisk/logger.h>
00101 
00102 #ifdef LONG_LONG_MIN
00103 #define QUAD_MIN LONG_LONG_MIN
00104 #endif
00105 #ifdef LONG_LONG_MAX
00106 #define QUAD_MAX LONG_LONG_MAX
00107 #endif
00108 
00109 #  if ! defined(QUAD_MIN)
00110 #   define QUAD_MIN     (-0x7fffffffffffffffL-1)
00111 #  endif
00112 #  if ! defined(QUAD_MAX)
00113 #   define QUAD_MAX     (0x7fffffffffffffffL)
00114 #  endif
00115 
00116 #define YYPARSE_PARAM kota
00117 #define YYLEX_PARAM kota
00118 
00119 /* #define ast_log fprintf
00120 #define LOG_WARNING stderr */
00121   
00122 enum valtype {
00123    integer, numeric_string, string
00124 } ;
00125 
00126 struct val {
00127    enum valtype type;
00128    union {
00129       char *s;
00130       quad_t i;
00131    } u;
00132 } ;
00133 
00134 struct parser_control {
00135    struct val *result;
00136    int pipa;
00137    char *arg_orig;
00138    char *argv;
00139    char *ptrptr;
00140    int firsttoken;
00141 } ;
00142 
00143 static int     chk_div __P((quad_t, quad_t));
00144 static int     chk_minus __P((quad_t, quad_t, quad_t));
00145 static int     chk_plus __P((quad_t, quad_t, quad_t));
00146 static int     chk_times __P((quad_t, quad_t, quad_t));
00147 static void    free_value __P((struct val *));
00148 static int     is_zero_or_null __P((struct val *));
00149 static int     isstring __P((struct val *));
00150 static struct val *make_integer __P((quad_t));
00151 static struct val *make_str __P((const char *));
00152 static struct val *op_and __P((struct val *, struct val *));
00153 static struct val *op_colon __P((struct val *, struct val *));
00154 static struct val *op_div __P((struct val *, struct val *));
00155 static struct val *op_eq __P((struct val *, struct val *));
00156 static struct val *op_ge __P((struct val *, struct val *));
00157 static struct val *op_gt __P((struct val *, struct val *));
00158 static struct val *op_le __P((struct val *, struct val *));
00159 static struct val *op_lt __P((struct val *, struct val *));
00160 static struct val *op_minus __P((struct val *, struct val *));
00161 static struct val *op_ne __P((struct val *, struct val *));
00162 static struct val *op_or __P((struct val *, struct val *));
00163 static struct val *op_plus __P((struct val *, struct val *));
00164 static struct val *op_rem __P((struct val *, struct val *));
00165 static struct val *op_times __P((struct val *, struct val *));
00166 static quad_t     to_integer __P((struct val *));
00167 static void    to_string __P((struct val *));
00168 
00169 /* uh, if I want to predeclare yylex with a YYLTYPE, I have to predeclare the yyltype... sigh */
00170 typedef struct yyltype
00171 {
00172   int first_line;
00173   int first_column;
00174 
00175   int last_line;
00176   int last_column;
00177 } yyltype;
00178 
00179 # define YYLTYPE yyltype
00180 # define YYLTYPE_IS_TRIVIAL 1
00181 
00182 static int     ast_yyerror __P((const char *,YYLTYPE *, struct parser_control *));
00183 
00184 #define ast_yyerror(x) ast_yyerror(x,&yyloc,kota)
00185 
00186 
00187 
00188 /* Enabling traces.  */
00189 #ifndef YYDEBUG
00190 # define YYDEBUG 0
00191 #endif
00192 
00193 /* Enabling verbose error messages.  */
00194 #ifdef YYERROR_VERBOSE
00195 # undef YYERROR_VERBOSE
00196 # define YYERROR_VERBOSE 1
00197 #else
00198 # define YYERROR_VERBOSE 0
00199 #endif
00200 
00201 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
00202 #line 116 "ast_expr.y"
00203 typedef union YYSTYPE {
00204    struct val *val;
00205 } YYSTYPE;
00206 /* Line 190 of yacc.c.  */
00207 #line 208 "ast_expr.c"
00208 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
00209 # define YYSTYPE_IS_DECLARED 1
00210 # define YYSTYPE_IS_TRIVIAL 1
00211 #endif
00212 
00213 #if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED)
00214 typedef struct YYLTYPE
00215 {
00216   int first_line;
00217   int first_column;
00218   int last_line;
00219   int last_column;
00220 } YYLTYPE;
00221 # define yyltype YYLTYPE /* obsolescent; will be withdrawn */
00222 # define YYLTYPE_IS_DECLARED 1
00223 # define YYLTYPE_IS_TRIVIAL 1
00224 #endif
00225 
00226 
00227 /* Copy the second part of user declarations.  */
00228 #line 120 "ast_expr.y"
00229 
00230 static int     ast_yylex __P((YYSTYPE *, YYLTYPE *, struct parser_control *));
00231 
00232 
00233 /* Line 213 of yacc.c.  */
00234 #line 235 "ast_expr.c"
00235 
00236 #if ! defined (yyoverflow) || YYERROR_VERBOSE
00237 
00238 # ifndef YYFREE
00239 #  define YYFREE free
00240 # endif
00241 # ifndef YYMALLOC
00242 #  define YYMALLOC malloc
00243 # endif
00244 
00245 /* The parser invokes alloca or malloc; define the necessary symbols.  */
00246 
00247 # ifdef YYSTACK_USE_ALLOCA
00248 #  if YYSTACK_USE_ALLOCA
00249 #   ifdef __GNUC__
00250 #    define YYSTACK_ALLOC __builtin_alloca
00251 #   else
00252 #    define YYSTACK_ALLOC alloca
00253 #   endif
00254 #  endif
00255 # endif
00256 
00257 # ifdef YYSTACK_ALLOC
00258    /* Pacify GCC's `empty if-body' warning. */
00259 #  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
00260 # else
00261 #  if defined (__STDC__) || defined (__cplusplus)
00262 #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
00263 #   define YYSIZE_T size_t
00264 #  endif
00265 #  define YYSTACK_ALLOC YYMALLOC
00266 #  define YYSTACK_FREE YYFREE
00267 # endif
00268 #endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */
00269 
00270 
00271 #if (! defined (yyoverflow) \
00272      && (! defined (__cplusplus) \
00273     || (defined (YYLTYPE_IS_TRIVIAL) && YYLTYPE_IS_TRIVIAL \
00274              && defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))
00275 
00276 /* A type that is properly aligned for any stack member.  */
00277 union yyalloc
00278 {
00279   short int yyss;
00280   YYSTYPE yyvs;
00281     YYLTYPE yyls;
00282 };
00283 
00284 /* The size of the maximum gap between one aligned stack and the next.  */
00285 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
00286 
00287 /* The size of an array large to enough to hold all stacks, each with
00288    N elements.  */
00289 # define YYSTACK_BYTES(N) \
00290      ((N) * (sizeof (short int) + sizeof (YYSTYPE) + sizeof (YYLTYPE))  \
00291       + 2 * YYSTACK_GAP_MAXIMUM)
00292 
00293 /* Copy COUNT objects from FROM to TO.  The source and destination do
00294    not overlap.  */
00295 # ifndef YYCOPY
00296 #  if defined (__GNUC__) && 1 < __GNUC__
00297 #   define YYCOPY(To, From, Count) \
00298       __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
00299 #  else
00300 #   define YYCOPY(To, From, Count)     \
00301       do             \
00302    {              \
00303      register YYSIZE_T yyi;      \
00304      for (yyi = 0; yyi < (Count); yyi++)  \
00305        (To)[yyi] = (From)[yyi];     \
00306    }              \
00307       while (0)
00308 #  endif
00309 # endif
00310 
00311 /* Relocate STACK from its old location to the new one.  The
00312    local variables YYSIZE and YYSTACKSIZE give the old and new number of
00313    elements in the stack, and YYPTR gives the new location of the
00314    stack.  Advance YYPTR to a properly aligned location for the next
00315    stack.  */
00316 # define YYSTACK_RELOCATE(Stack)             \
00317     do                           \
00318       {                          \
00319    YYSIZE_T yynewbytes;                \
00320    YYCOPY (&yyptr->Stack, Stack, yysize);          \
00321    Stack = &yyptr->Stack;                 \
00322    yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
00323    yyptr += yynewbytes / sizeof (*yyptr);          \
00324       }                          \
00325     while (0)
00326 
00327 #endif
00328 
00329 #if defined (__STDC__) || defined (__cplusplus)
00330    typedef signed char yysigned_char;
00331 #else
00332    typedef short int yysigned_char;
00333 #endif
00334 
00335 /* YYFINAL -- State number of the termination state. */
00336 #define YYFINAL  6
00337 /* YYLAST -- Last index in YYTABLE.  */
00338 #define YYLAST   83
00339 
00340 /* YYNTOKENS -- Number of terminals. */
00341 #define YYNTOKENS  20
00342 /* YYNNTS -- Number of nonterminals. */
00343 #define YYNNTS  3
00344 /* YYNRULES -- Number of rules. */
00345 #define YYNRULES  18
00346 /* YYNRULES -- Number of states. */
00347 #define YYNSTATES  36
00348 
00349 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
00350 #define YYUNDEFTOK  2
00351 #define YYMAXUTOK   261
00352 
00353 #define YYTRANSLATE(YYX)                  \
00354   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
00355 
00356 /* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
00357 static const unsigned char yytranslate[] =
00358 {
00359        0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00360        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00361        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00362        2,     2,     2,     2,     2,     2,     2,    15,     4,     2,
00363       18,    19,    13,    11,     2,    12,     2,    14,     2,     2,
00364        2,     2,     2,     2,     2,     2,     2,     2,    16,     2,
00365        7,     5,     6,     2,     2,     2,     2,     2,     2,     2,
00366        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00367        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00368        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00369        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00370        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00371        2,     2,     2,     2,     3,     2,     2,     2,     2,     2,
00372        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00373        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00374        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00375        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00376        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00377        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00378        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00379        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00380        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00381        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00382        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00383        2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
00384        2,     2,     2,     2,     2,     2,     1,     2,     8,     9,
00385       10,    17
00386 };
00387 
00388 #if YYDEBUG
00389 /* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
00390    YYRHS.  */
00391 static const unsigned char yyprhs[] =
00392 {
00393        0,     0,     3,     5,     7,    11,    15,    19,    23,    27,
00394       31,    35,    39,    43,    47,    51,    55,    59,    63
00395 };
00396 
00397 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
00398 static const yysigned_char yyrhs[] =
00399 {
00400       21,     0,    -1,    22,    -1,    17,    -1,    18,    22,    19,
00401       -1,    22,     3,    22,    -1,    22,     4,    22,    -1,    22,
00402        5,    22,    -1,    22,     6,    22,    -1,    22,     7,    22,
00403       -1,    22,    10,    22,    -1,    22,     9,    22,    -1,    22,
00404        8,    22,    -1,    22,    11,    22,    -1,    22,    12,    22,
00405       -1,    22,    13,    22,    -1,    22,    14,    22,    -1,    22,
00406       15,    22,    -1,    22,    16,    22,    -1
00407 };
00408 
00409 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
00410 static const unsigned char yyrline[] =
00411 {
00412        0,   137,   137,   140,   141,   142,   143,   144,   145,   146,
00413      147,   148,   149,   150,   151,   152,   153,   154,   155
00414 };
00415 #endif
00416 
00417 #if YYDEBUG || YYERROR_VERBOSE
00418 /* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
00419    First, the terminals, then, starting at YYNTOKENS, nonterminals. */
00420 static const char *const yytname[] =
00421 {
00422   "$end", "error", "$undefined", "'|'", "'&'", "'='", "'>'", "'<'", "NE",
00423   "LE", "GE", "'+'", "'-'", "'*'", "'/'", "'%'", "':'", "TOKEN", "'('",
00424   "')'", "$accept", "start", "expr", 0
00425 };
00426 #endif
00427 
00428 # ifdef YYPRINT
00429 /* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
00430    token YYLEX-NUM.  */
00431 static const unsigned short int yytoknum[] =
00432 {
00433        0,   256,   257,   124,    38,    61,    62,    60,   258,   259,
00434      260,    43,    45,    42,    47,    37,    58,   261,    40,    41
00435 };
00436 # endif
00437 
00438 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
00439 static const unsigned char yyr1[] =
00440 {
00441        0,    20,    21,    22,    22,    22,    22,    22,    22,    22,
00442       22,    22,    22,    22,    22,    22,    22,    22,    22
00443 };
00444 
00445 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
00446 static const unsigned char yyr2[] =
00447 {
00448        0,     2,     1,     1,     3,     3,     3,     3,     3,     3,
00449        3,     3,     3,     3,     3,     3,     3,     3,     3
00450 };
00451 
00452 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
00453    STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
00454    means the default is an error.  */
00455 static const unsigned char yydefact[] =
00456 {
00457        0,     3,     0,     0,     2,     0,     1,     0,     0,     0,
00458        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
00459        0,     4,     5,     6,     7,     8,     9,    12,    11,    10,
00460       13,    14,    15,    16,    17,    18
00461 };
00462 
00463 /* YYDEFGOTO[NTERM-NUM]. */
00464 static const yysigned_char yydefgoto[] =
00465 {
00466       -1,     3,     4
00467 };
00468 
00469 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
00470    STATE-NUM.  */
00471 #define YYPACT_NINF -13
00472 static const yysigned_char yypact[] =
00473 {
00474       65,   -13,    65,    34,    33,    16,   -13,    65,    65,    65,
00475       65,    65,    65,    65,    65,    65,    65,    65,    65,    65,
00476       65,   -13,    46,    58,    64,    64,    64,    64,    64,    64,
00477      -12,   -12,    17,    17,    17,   -13
00478 };
00479 
00480 /* YYPGOTO[NTERM-NUM].  */
00481 static const yysigned_char yypgoto[] =
00482 {
00483      -13,   -13,    -2
00484 };
00485 
00486 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
00487    positive, shift that token.  If negative, reduce the rule which
00488    number is the opposite.  If zero, do what YYDEFACT says.
00489    If YYTABLE_NINF, syntax error.  */
00490 #define YYTABLE_NINF -1
00491 static const unsigned char yytable[] =
00492 {
00493        5,    17,    18,    19,    20,    22,    23,    24,    25,    26,
00494       27,    28,    29,    30,    31,    32,    33,    34,    35,     7,
00495        8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
00496       18,    19,    20,    20,     6,    21,     7,     8,     9,    10,
00497       11,    12,    13,    14,    15,    16,    17,    18,    19,    20,
00498        8,     9,    10,    11,    12,    13,    14,    15,    16,    17,
00499       18,    19,    20,     9,    10,    11,    12,    13,    14,    15,
00500       16,    17,    18,    19,    20,    15,    16,    17,    18,    19,
00501       20,     0,     1,     2
00502 };
00503 
00504 static const yysigned_char yycheck[] =
00505 {
00506        2,    13,    14,    15,    16,     7,     8,     9,    10,    11,
00507       12,    13,    14,    15,    16,    17,    18,    19,    20,     3,
00508        4,     5,     6,     7,     8,     9,    10,    11,    12,    13,
00509       14,    15,    16,    16,     0,    19,     3,     4,     5,     6,
00510        7,     8,     9,    10,    11,    12,    13,    14,    15,    16,
00511        4,     5,     6,     7,     8,     9,    10,    11,    12,    13,
00512       14,    15,    16,     5,     6,     7,     8,     9,    10,    11,
00513       12,    13,    14,    15,    16,    11,    12,    13,    14,    15,
00514       16,    -1,    17,    18
00515 };
00516 
00517 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
00518    symbol of state STATE-NUM.  */
00519 static const unsigned char yystos[] =
00520 {
00521        0,    17,    18,    21,    22,    22,     0,     3,     4,     5,
00522        6,     7,     8,     9,    10,    11,    12,    13,    14,    15,
00523       16,    19,    22,    22,    22,    22,    22,    22,    22,    22,
00524       22,    22,    22,    22,    22,    22
00525 };
00526 
00527 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
00528 # define YYSIZE_T __SIZE_TYPE__
00529 #endif
00530 #if ! defined (YYSIZE_T) && defined (size_t)
00531 # define YYSIZE_T size_t
00532 #endif
00533 #if ! defined (YYSIZE_T)
00534 # if defined (__STDC__) || defined (__cplusplus)
00535 #  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
00536 #  define YYSIZE_T size_t
00537 # endif
00538 #endif
00539 #if ! defined (YYSIZE_T)
00540 # define YYSIZE_T unsigned int
00541 #endif
00542 
00543 #define yyerrok      (yyerrstatus = 0)
00544 #define yyclearin (yychar = YYEMPTY)
00545 #define YYEMPTY      (-2)
00546 #define YYEOF     0
00547 
00548 #define YYACCEPT  goto yyacceptlab
00549 #define YYABORT      goto yyabortlab
00550 #define YYERROR      goto yyerrorlab
00551 
00552 
00553 /* Like YYERROR except do call yyerror.  This remains here temporarily
00554    to ease the transition to the new meaning of YYERROR, for GCC.
00555    Once GCC version 2 has supplanted version 1, this can go.  */
00556 
00557 #define YYFAIL    goto yyerrlab
00558 
00559 #define YYRECOVERING()  (!!yyerrstatus)
00560 
00561 #define YYBACKUP(Token, Value)               \
00562 do                      \
00563   if (yychar == YYEMPTY && yylen == 1)          \
00564     {                      \
00565       yychar = (Token);                \
00566       yylval = (Value);                \
00567       yytoken = YYTRANSLATE (yychar);           \
00568       YYPOPSTACK;                \
00569       goto yybackup;                \
00570     }                      \
00571   else                        \
00572     {                         \
00573       yyerror ("syntax error: cannot back up");\
00574       YYERROR;                   \
00575     }                      \
00576 while (0)
00577 
00578 
00579 #define YYTERROR  1
00580 #define YYERRCODE 256
00581 
00582 
00583 /* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
00584    If N is 0, then set CURRENT to the empty location which ends
00585    the previous symbol: RHS[0] (always defined).  */
00586 
00587 #define YYRHSLOC(Rhs, K) ((Rhs)[K])
00588 #ifndef YYLLOC_DEFAULT
00589 # define YYLLOC_DEFAULT(Current, Rhs, N)           \
00590     do                           \
00591       if (N)                        \
00592    {                       \
00593      (Current).first_line   = YYRHSLOC (Rhs, 1).first_line; \
00594      (Current).first_column = YYRHSLOC (Rhs, 1).first_column;  \
00595      (Current).last_line    = YYRHSLOC (Rhs, N).last_line;     \
00596      (Current).last_column  = YYRHSLOC (Rhs, N).last_column;   \
00597    }                       \
00598       else                       \
00599    {                       \
00600      (Current).first_line   = (Current).last_line   =    \
00601        YYRHSLOC (Rhs, 0).last_line;          \
00602      (Current).first_column = (Current).last_column =    \
00603        YYRHSLOC (Rhs, 0).last_column;           \
00604    }                       \
00605     while (0)
00606 #endif
00607 
00608 
00609 /* YY_LOCATION_PRINT -- Print the location on the stream.
00610    This macro was not mandated originally: define only if we know
00611    we won't break user code: when these are the locations we know.  */
00612 
00613 #ifndef YY_LOCATION_PRINT
00614 # if YYLTYPE_IS_TRIVIAL
00615 #  define YY_LOCATION_PRINT(File, Loc)       \
00616      fprintf (File, "%d.%d-%d.%d",        \
00617               (Loc).first_line, (Loc).first_column,   \
00618               (Loc).last_line,  (Loc).last_column)
00619 # else
00620 #  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
00621 # endif
00622 #endif
00623 
00624 
00625 /* YYLEX -- calling `yylex' with the right arguments.  */
00626 
00627 #ifdef YYLEX_PARAM
00628 # define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
00629 #else
00630 # define YYLEX yylex (&yylval, &yylloc)
00631 #endif
00632 
00633 /* Enable debugging if requested.  */
00634 #if YYDEBUG
00635 
00636 # ifndef YYFPRINTF
00637 #  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
00638 #  define YYFPRINTF fprintf
00639 # endif
00640 
00641 # define YYDPRINTF(Args)         \
00642 do {                 \
00643   if (yydebug)             \
00644     YYFPRINTF Args;           \
00645 } while (0)
00646 
00647 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)      \
00648 do {                       \
00649   if (yydebug)                   \
00650     {                      \
00651       YYFPRINTF (stderr, "%s ", Title);            \
00652       yysymprint (stderr,              \
00653                   Type, Value, Location); \
00654       YYFPRINTF (stderr, "\n");              \
00655     }                      \
00656 } while (0)
00657 
00658 /*------------------------------------------------------------------.
00659 | yy_stack_print -- Print the state stack from its BOTTOM up to its |
00660 | TOP (included).                                                   |
00661 `------------------------------------------------------------------*/
00662 
00663 #if defined (__STDC__) || defined (__cplusplus)
00664 static void
00665 yy_stack_print (short int *bottom, short int *top)
00666 #else
00667 static void
00668 yy_stack_print (bottom, top)
00669     short int *bottom;
00670     short int *top;
00671 #endif
00672 {
00673   YYFPRINTF (stderr, "Stack now");
00674   for (/* Nothing. */; bottom <= top; ++bottom)
00675     YYFPRINTF (stderr, " %d", *bottom);
00676   YYFPRINTF (stderr, "\n");
00677 }
00678 
00679 # define YY_STACK_PRINT(Bottom, Top)            \
00680 do {                       \
00681   if (yydebug)                   \
00682     yy_stack_print ((Bottom), (Top));           \
00683 } while (0)
00684 
00685 
00686 /*------------------------------------------------.
00687 | Report that the YYRULE is going to be reduced.  |
00688 `------------------------------------------------*/
00689 
00690 #if defined (__STDC__) || defined (__cplusplus)
00691 static void
00692 yy_reduce_print (int yyrule)
00693 #else
00694 static void
00695 yy_reduce_print (yyrule)
00696     int yyrule;
00697 #endif
00698 {
00699   int yyi;
00700   unsigned int yylno = yyrline[yyrule];
00701   YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
00702              yyrule - 1, yylno);
00703   /* Print the symbols being reduced, and their result.  */
00704   for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
00705     YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
00706   YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
00707 }
00708 
00709 # define YY_REDUCE_PRINT(Rule)      \
00710 do {              \
00711   if (yydebug)          \
00712     yy_reduce_print (Rule);      \
00713 } while (0)
00714 
00715 /* Nonzero means print parse trace.  It is left uninitialized so that
00716    multiple parsers can coexist.  */
00717 int yydebug;
00718 #else /* !YYDEBUG */
00719 # define YYDPRINTF(Args)
00720 # define YY_SYMBOL_PRINT(Title, Type, Value, Location)
00721 # define YY_STACK_PRINT(Bottom, Top)
00722 # define YY_REDUCE_PRINT(Rule)
00723 #endif /* !YYDEBUG */
00724 
00725 
00726 /* YYINITDEPTH -- initial size of the parser's stacks.  */
00727 #ifndef  YYINITDEPTH
00728 # define YYINITDEPTH 200
00729 #endif
00730 
00731 /* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
00732    if the built-in stack extension method is used).
00733 
00734    Do not make this value too large; the results are undefined if
00735    SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
00736    evaluated with infinite-precision integer arithmetic.  */
00737 
00738 #ifndef YYMAXDEPTH
00739 # define YYMAXDEPTH 10000
00740 #endif
00741 
00742 
00743 
00744 #if YYERROR_VERBOSE
00745 
00746 # ifndef yystrlen
00747 #  if defined (__GLIBC__) && defined (_STRING_H)
00748 #   define yystrlen strlen
00749 #  else
00750 /* Return the length of YYSTR.  */
00751 static YYSIZE_T
00752 #   if defined (__STDC__) || defined (__cplusplus)
00753 yystrlen (const char *yystr)
00754 #   else
00755 yystrlen (yystr)
00756      const char *yystr;
00757 #   endif
00758 {
00759   register const char *yys = yystr;
00760 
00761   while (*yys++ != '\0')
00762     continue;
00763 
00764   return yys - yystr - 1;
00765 }
00766 #  endif
00767 # endif
00768 
00769 # ifndef yystpcpy
00770 #  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
00771 #   define yystpcpy stpcpy
00772 #  else
00773 /* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
00774    YYDEST.  */
00775 static char *
00776 #   if defined (__STDC__) || defined (__cplusplus)
00777 yystpcpy (char *yydest, const char *yysrc)
00778 #   else
00779 yystpcpy (yydest, yysrc)
00780      char *yydest;
00781      const char *yysrc;
00782 #   endif
00783 {
00784   register char *yyd = yydest;
00785   register const char *yys = yysrc;
00786 
00787   while ((*yyd++ = *yys++) != '\0')
00788     continue;
00789 
00790   return yyd - 1;
00791 }
00792 #  endif
00793 # endif
00794 
00795 #endif /* !YYERROR_VERBOSE */
00796 
00797 
00798 
00799 #if YYDEBUG
00800 /*--------------------------------.
00801 | Print this symbol on YYOUTPUT.  |
00802 `--------------------------------*/
00803 
00804 #if defined (__STDC__) || defined (__cplusplus)
00805 static void
00806 yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
00807 #else
00808 static void
00809 yysymprint (yyoutput, yytype, yyvaluep, yylocationp)
00810     FILE *yyoutput;
00811     int yytype;
00812     YYSTYPE *yyvaluep;
00813     YYLTYPE *yylocationp;
00814 #endif
00815 {
00816   /* Pacify ``unused variable'' warnings.  */
00817   (void) yyvaluep;
00818   (void) yylocationp;
00819 
00820   if (yytype < YYNTOKENS)
00821     YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
00822   else
00823     YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
00824 
00825   YY_LOCATION_PRINT (yyoutput, *yylocationp);
00826   fprintf (yyoutput, ": ");
00827 
00828 # ifdef YYPRINT
00829   if (yytype < YYNTOKENS)
00830     YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
00831 # endif
00832   switch (yytype)
00833     {
00834       default:
00835         break;
00836     }
00837   YYFPRINTF (yyoutput, ")");
00838 }
00839 
00840 #endif /* ! YYDEBUG */
00841 /*-----------------------------------------------.
00842 | Release the memory associated to this symbol.  |
00843 `-----------------------------------------------*/
00844 
00845 #if defined (__STDC__) || defined (__cplusplus)
00846 static void
00847 yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
00848 #else
00849 static void
00850 yydestruct (yymsg, yytype, yyvaluep, yylocationp)
00851     const char *yymsg;
00852     int yytype;
00853     YYSTYPE *yyvaluep;
00854     YYLTYPE *yylocationp;
00855 #endif
00856 {
00857   /* Pacify ``unused variable'' warnings.  */
00858   (void) yyvaluep;
00859   (void) yylocationp;
00860 
00861   if (!yymsg)
00862     yymsg = "Deleting";
00863   YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
00864 
00865   switch (yytype)
00866     {
00867 
00868       default:
00869         break;
00870     }
00871 }
00872 
00873 
00874 /* Prevent warnings from -Wmissing-prototypes.  */
00875 
00876 #ifdef YYPARSE_PARAM
00877 # if defined (__STDC__) || defined (__cplusplus)
00878 int yyparse (void *YYPARSE_PARAM);
00879 # else
00880 int yyparse ();
00881 # endif
00882 #else /* ! YYPARSE_PARAM */
00883 #if defined (__STDC__) || defined (__cplusplus)
00884 int yyparse (void);
00885 #else
00886 int yyparse ();
00887 #endif
00888 #endif /* ! YYPARSE_PARAM */
00889 
00890 
00891 
00892 
00893 
00894 
00895 /*----------.
00896 | yyparse.  |
00897 `----------*/
00898 
00899 #ifdef YYPARSE_PARAM
00900 # if defined (__STDC__) || defined (__cplusplus)
00901 int yyparse (void *YYPARSE_PARAM)
00902 # else
00903 int yyparse (YYPARSE_PARAM)
00904   void *YYPARSE_PARAM;
00905 # endif
00906 #else /* ! YYPARSE_PARAM */
00907 #if defined (__STDC__) || defined (__cplusplus)
00908 int
00909 yyparse (void)
00910 #else
00911 int
00912 yyparse ()
00913 
00914 #endif
00915 #endif
00916 {
00917   /* The look-ahead symbol.  */
00918 int yychar;
00919 
00920 /* The semantic value of the look-ahead symbol.  */
00921 YYSTYPE yylval;
00922 
00923 /* Number of syntax errors so far.  */
00924 int yynerrs;
00925 /* Location data for the look-ahead symbol.  */
00926 YYLTYPE yylloc;
00927 
00928   register int yystate;
00929   register int yyn;
00930   int yyresult;
00931   /* Number of tokens to shift before error messages enabled.  */
00932   int yyerrstatus;
00933   /* Look-ahead token as an internal (translated) token number.  */
00934   int yytoken = 0;
00935 
00936   /* Three stacks and their tools:
00937      `yyss': related to states,
00938      `yyvs': related to semantic values,
00939      `yyls': related to locations.
00940 
00941      Refer to the stacks thru separate pointers, to allow yyoverflow
00942      to reallocate them elsewhere.  */
00943 
00944   /* The state stack.  */
00945   short int yyssa[YYINITDEPTH];
00946   short int *yyss = yyssa;
00947   register short int *yyssp;
00948 
00949   /* The semantic value stack.  */
00950   YYSTYPE yyvsa[YYINITDEPTH];
00951   YYSTYPE *yyvs = yyvsa;
00952   register YYSTYPE *yyvsp;
00953 
00954   /* The location stack.  */
00955   YYLTYPE yylsa[YYINITDEPTH];
00956   YYLTYPE *yyls = yylsa;
00957   YYLTYPE *yylsp;
00958   /* The locations where the error started and ended. */
00959   YYLTYPE yyerror_range[2];
00960 
00961 #define YYPOPSTACK   (yyvsp--, yyssp--, yylsp--)
00962 
00963   YYSIZE_T yystacksize = YYINITDEPTH;
00964 
00965   /* The variables used to return semantic value and location from the
00966      action routines.  */
00967   YYSTYPE yyval;
00968   YYLTYPE yyloc;
00969 
00970   /* When reducing, the number of symbols on the RHS of the reduced
00971      rule.  */
00972   int yylen;
00973 
00974   YYDPRINTF ((stderr, "Starting parse\n"));
00975 
00976   yystate = 0;
00977   yyerrstatus = 0;
00978   yynerrs = 0;
00979   yychar = YYEMPTY;     /* Cause a token to be read.  */
00980 
00981   /* Initialize stack pointers.
00982      Waste one element of value and location stack
00983      so that they stay on the same level as the state stack.
00984      The wasted elements are never initialized.  */
00985 
00986   yyssp = yyss;
00987   yyvsp = yyvs;
00988   yylsp = yyls;
00989 #if YYLTYPE_IS_TRIVIAL
00990   /* Initialize the default location before parsing starts.  */
00991   yylloc.first_line   = yylloc.last_line   = 1;
00992   yylloc.first_column = yylloc.last_column = 0;
00993 #endif
00994 
00995 
00996   yyvsp[0] = yylval;
00997     yylsp[0] = yylloc;
00998 
00999   goto yysetstate;
01000 
01001 /*------------------------------------------------------------.
01002 | yynewstate -- Push a new state, which is found in yystate.  |
01003 `------------------------------------------------------------*/
01004  yynewstate:
01005   /* In all cases, when you get here, the value and location stacks
01006      have just been pushed. so pushing a state here evens the stacks.
01007      */
01008   yyssp++;
01009 
01010  yysetstate:
01011   *yyssp = yystate;
01012 
01013   if (yyss + yystacksize - 1 <= yyssp)
01014     {
01015       /* Get the current used size of the three stacks, in elements.  */
01016       YYSIZE_T yysize = yyssp - yyss + 1;
01017 
01018 #ifdef yyoverflow
01019       {
01020    /* Give user a chance to reallocate the stack. Use copies of
01021       these so that the &'s don't force the real ones into
01022       memory.  */
01023    YYSTYPE *yyvs1 = yyvs;
01024    short int *yyss1 = yyss;
01025    YYLTYPE *yyls1 = yyls;
01026 
01027    /* Each stack pointer address is followed by the size of the
01028       data in use in that stack, in bytes.  This used to be a
01029       conditional around just the two extra args, but that might
01030       be undefined if yyoverflow is a macro.  */
01031    yyoverflow ("parser stack overflow",
01032           &yyss1, yysize * sizeof (*yyssp),
01033           &yyvs1, yysize * sizeof (*yyvsp),
01034           &yyls1, yysize * sizeof (*yylsp),
01035           &yystacksize);
01036    yyls = yyls1;
01037    yyss = yyss1;
01038    yyvs = yyvs1;
01039       }
01040 #else /* no yyoverflow */
01041 # ifndef YYSTACK_RELOCATE
01042       goto yyoverflowlab;
01043 # else
01044       /* Extend the stack our own way.  */
01045       if (YYMAXDEPTH <= yystacksize)
01046    goto yyoverflowlab;
01047       yystacksize *= 2;
01048       if (YYMAXDEPTH < yystacksize)
01049    yystacksize = YYMAXDEPTH;
01050 
01051       {
01052    short int *yyss1 = yyss;
01053    union yyalloc *yyptr =
01054      (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
01055    if (! yyptr)
01056      goto yyoverflowlab;
01057    YYSTACK_RELOCATE (yyss);
01058    YYSTACK_RELOCATE (yyvs);
01059    YYSTACK_RELOCATE (yyls);
01060 #  undef YYSTACK_RELOCATE
01061    if (yyss1 != yyssa)
01062      YYSTACK_FREE (yyss1);
01063       }
01064 # endif
01065 #endif /* no yyoverflow */
01066 
01067       yyssp = yyss + yysize - 1;
01068       yyvsp = yyvs + yysize - 1;
01069       yylsp = yyls + yysize - 1;
01070 
01071       YYDPRINTF ((stderr, "Stack size increased to %lu\n",
01072         (unsigned long int) yystacksize));
01073 
01074       if (yyss + yystacksize - 1 <= yyssp)
01075    YYABORT;
01076     }
01077 
01078   YYDPRINTF ((stderr, "Entering state %d\n", yystate));
01079 
01080   goto yybackup;
01081 
01082 /*-----------.
01083 | yybackup.  |
01084 `-----------*/
01085 yybackup:
01086 
01087 /* Do appropriate processing given the current state.  */
01088 /* Read a look-ahead token if we need one and don't already have one.  */
01089 /* yyresume: */
01090 
01091   /* First try to decide what to do without reference to look-ahead token.  */
01092 
01093   yyn = yypact[yystate];
01094   if (yyn == YYPACT_NINF)
01095     goto yydefault;
01096 
01097   /* Not known => get a look-ahead token if don't already have one.  */
01098 
01099   /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
01100   if (yychar == YYEMPTY)
01101     {
01102       YYDPRINTF ((stderr, "Reading a token: "));
01103       yychar = YYLEX;
01104     }
01105 
01106   if (yychar <= YYEOF)
01107     {
01108       yychar = yytoken = YYEOF;
01109       YYDPRINTF ((stderr, "Now at end of input.\n"));
01110     }
01111   else
01112     {
01113       yytoken = YYTRANSLATE (yychar);
01114       YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
01115     }
01116 
01117   /* If the proper action on seeing token YYTOKEN is to reduce or to
01118      detect an error, take that action.  */
01119   yyn += yytoken;
01120   if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
01121     goto yydefault;
01122   yyn = yytable[yyn];
01123   if (yyn <= 0)
01124     {
01125       if (yyn == 0 || yyn == YYTABLE_NINF)
01126    goto yyerrlab;
01127       yyn = -yyn;
01128       goto yyreduce;
01129     }
01130 
01131   if (yyn == YYFINAL)
01132     YYACCEPT;
01133 
01134   /* Shift the look-ahead token.  */
01135   YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
01136 
01137   /* Discard the token being shifted unless it is eof.  */
01138   if (yychar != YYEOF)
01139     yychar = YYEMPTY;
01140 
01141   *++yyvsp = yylval;
01142   *++yylsp = yylloc;
01143 
01144   /* Count tokens shifted since error; after three, turn off error
01145      status.  */
01146   if (yyerrstatus)
01147     yyerrstatus--;
01148 
01149   yystate = yyn;
01150   goto yynewstate;
01151 
01152 
01153 /*-----------------------------------------------------------.
01154 | yydefault -- do the default action for the current state.  |
01155 `-----------------------------------------------------------*/
01156 yydefault:
01157   yyn = yydefact[yystate];
01158   if (yyn == 0)
01159     goto yyerrlab;
01160   goto yyreduce;
01161 
01162 
01163 /*-----------------------------.
01164 | yyreduce -- Do a reduction.  |
01165 `-----------------------------*/
01166 yyreduce:
01167   /* yyn is the number of a rule to reduce with.  */
01168   yylen = yyr2[yyn];
01169 
01170   /* If YYLEN is nonzero, implement the default value of the action:
01171      `$$ = $1'.
01172 
01173      Otherwise, the following line sets YYVAL to garbage.
01174      This behavior is undocumented and Bison
01175      users should not rely upon it.  Assigning to YYVAL
01176      unconditionally makes the parser a bit smaller, and it avoids a
01177      GCC warning that YYVAL may be used uninitialized.  */
01178   yyval = yyvsp[1-yylen];
01179 
01180   /* Default location. */
01181   YYLLOC_DEFAULT (yyloc, yylsp - yylen, yylen);
01182   YY_REDUCE_PRINT (yyn);
01183   switch (yyn)
01184     {
01185         case 2:
01186 #line 137 "ast_expr.y"
01187     { ((struct parser_control *)kota)->result = (yyval.val); ;}
01188     break;
01189 
01190   case 4:
01191 #line 141 "ast_expr.y"
01192     { (yyval.val) = (yyvsp[-1].val); (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;}
01193     break;
01194 
01195   case 5:
01196 #line 142 "ast_expr.y"
01197     { (yyval.val) = op_or ((yyvsp[-2].val), (yyvsp[0].val)); (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;}
01198     break;
01199 
01200   case 6:
01201 #line 143 "ast_expr.y"
01202     { (yyval.val) = op_and ((yyvsp[-2].val), (yyvsp[0].val)); (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;}
01203     break;
01204 
01205   case 7:
01206 #line 144 "ast_expr.y"
01207     { (yyval.val) = op_eq ((yyvsp[-2].val), (yyvsp[0].val)); (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;}
01208     break;
01209 
01210   case 8:
01211 #line 145 "ast_expr.y"
01212     { (yyval.val) = op_gt ((yyvsp[-2].val), (yyvsp[0].val)); (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;}
01213     break;
01214 
01215   case 9:
01216 #line 146 "ast_expr.y"
01217     { (yyval.val) = op_lt ((yyvsp[-2].val), (yyvsp[0].val)); (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;}
01218     break;
01219 
01220   case 10:
01221 #line 147 "ast_expr.y"
01222     { (yyval.val) = op_ge ((yyvsp[-2].val), (yyvsp[0].val)); (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;}
01223     break;
01224 
01225   case 11:
01226 #line 148 "ast_expr.y"
01227     { (yyval.val) = op_le ((yyvsp[-2].val), (yyvsp[0].val)); (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;}
01228     break;
01229 
01230   case 12:
01231 #line 149 "ast_expr.y"
01232     { (yyval.val) = op_ne ((yyvsp[-2].val), (yyvsp[0].val)); (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;}
01233     break;
01234 
01235   case 13:
01236 #line 150 "ast_expr.y"
01237     { (yyval.val) = op_plus ((yyvsp[-2].val), (yyvsp[0].val)); (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;}
01238     break;
01239 
01240   case 14:
01241 #line 151 "ast_expr.y"
01242     { (yyval.val) = op_minus ((yyvsp[-2].val), (yyvsp[0].val)); (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;}
01243     break;
01244 
01245   case 15:
01246 #line 152 "ast_expr.y"
01247     { (yyval.val) = op_times ((yyvsp[-2].val), (yyvsp[0].val)); (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;}
01248     break;
01249 
01250   case 16:
01251 #line 153 "ast_expr.y"
01252     { (yyval.val) = op_div ((yyvsp[-2].val), (yyvsp[0].val)); (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;}
01253     break;
01254 
01255   case 17:
01256 #line 154 "ast_expr.y"
01257     { (yyval.val) = op_rem ((yyvsp[-2].val), (yyvsp[0].val)); (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;}
01258     break;
01259 
01260   case 18:
01261 #line 155 "ast_expr.y"
01262     { (yyval.val) = op_colon ((yyvsp[-2].val), (yyvsp[0].val)); (yyloc).first_column = (yylsp[-2]).first_column; (yyloc).last_column = (yylsp[0]).last_column; (yyloc).first_line=0; (yyloc).last_line=0;;}
01263     break;
01264 
01265 
01266     }
01267 
01268 /* Line 1037 of yacc.c.  */
01269 #line 1270 "ast_expr.c"
01270 
01271   yyvsp -= yylen;
01272   yyssp -= yylen;
01273   yylsp -= yylen;
01274 
01275   YY_STACK_PRINT (yyss, yyssp);
01276 
01277   *++yyvsp = yyval;
01278   *++yylsp = yyloc;
01279 
01280   /* Now `shift' the result of the reduction.  Determine what state
01281      that goes to, based on the state we popped back to and the rule
01282      number reduced by.  */
01283 
01284   yyn = yyr1[yyn];
01285 
01286   yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
01287   if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
01288     yystate = yytable[yystate];
01289   else
01290     yystate = yydefgoto[yyn - YYNTOKENS];
01291 
01292   goto yynewstate;
01293 
01294 
01295 /*------------------------------------.
01296 | yyerrlab -- here on detecting error |
01297 `------------------------------------*/
01298 yyerrlab:
01299   /* If not already recovering from an error, report this error.  */
01300   if (!yyerrstatus)
01301     {
01302       ++yynerrs;
01303 #if YYERROR_VERBOSE
01304       yyn = yypact[yystate];
01305 
01306       if (YYPACT_NINF < yyn && yyn < YYLAST)
01307    {
01308      YYSIZE_T yysize = 0;
01309      int yytype = YYTRANSLATE (yychar);
01310      const char* yyprefix;
01311      char *yymsg;
01312      int yyx;
01313 
01314      /* Start YYX at -YYN if negative to avoid negative indexes in
01315         YYCHECK.  */
01316      int yyxbegin = yyn < 0 ? -yyn : 0;
01317 
01318      /* Stay within bounds of both yycheck and yytname.  */
01319      int yychecklim = YYLAST - yyn;
01320      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
01321      int yycount = 0;
01322 
01323      yyprefix = ", expecting ";
01324      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
01325        if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
01326          {
01327       yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
01328       yycount += 1;
01329       if (yycount == 5)
01330         {
01331           yysize = 0;
01332           break;
01333         }
01334          }
01335      yysize += (sizeof ("syntax error, unexpected ")
01336            + yystrlen (yytname[yytype]));
01337      yymsg = (char *) YYSTACK_ALLOC (yysize);
01338      if (yymsg != 0)
01339        {
01340          char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
01341          yyp = yystpcpy (yyp, yytname[yytype]);
01342 
01343          if (yycount < 5)
01344       {
01345         yyprefix = ", expecting ";
01346         for (yyx = yyxbegin; yyx < yyxend; ++yyx)
01347           if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
01348             {
01349          yyp = yystpcpy (yyp, yyprefix);
01350          yyp = yystpcpy (yyp, yytname[yyx]);
01351          yyprefix = " or ";
01352             }
01353       }
01354          yyerror (yymsg);
01355          YYSTACK_FREE (yymsg);
01356        }
01357      else
01358        yyerror ("syntax error; also virtual memory exhausted");
01359    }
01360       else
01361 #endif /* YYERROR_VERBOSE */
01362    yyerror ("syntax error");
01363     }
01364 
01365   yyerror_range[0] = yylloc;
01366 
01367   if (yyerrstatus == 3)
01368     {
01369       /* If just tried and failed to reuse look-ahead token after an
01370     error, discard it.  */
01371 
01372       if (yychar <= YYEOF)
01373         {
01374           /* If at end of input, pop the error token,
01375         then the rest of the stack, then return failure.  */
01376      if (yychar == YYEOF)
01377         for (;;)
01378           {
01379                  yyerror_range[0] = *yylsp;
01380        YYPOPSTACK;
01381        if (yyssp == yyss)
01382          YYABORT;
01383        yydestruct ("Error: popping",
01384                              yystos[*yyssp], yyvsp, yylsp);
01385           }
01386         }
01387       else
01388    {
01389      yydestruct ("Error: discarding", yytoken, &yylval, &yylloc);
01390      yychar = YYEMPTY;
01391    }
01392     }
01393 
01394   /* Else will try to reuse look-ahead token after shifting the error
01395      token.  */
01396   goto yyerrlab1;
01397 
01398 
01399 /*---------------------------------------------------.
01400 | yyerrorlab -- error raised explicitly by YYERROR.  |
01401 `---------------------------------------------------*/
01402 yyerrorlab:
01403 
01404 #ifdef __GNUC__
01405   /* Pacify GCC when the user code never invokes YYERROR and the label
01406      yyerrorlab therefore never appears in user code.  */
01407   if (0)
01408      goto yyerrorlab;
01409 #endif
01410 
01411   yyerror_range[0] = yylsp[1-yylen];
01412   yylsp -= yylen;
01413   yyvsp -= yylen;
01414   yyssp -= yylen;
01415   yystate = *yyssp;
01416   goto yyerrlab1;
01417 
01418 
01419 /*-------------------------------------------------------------.
01420 | yyerrlab1 -- common code for both syntax error and YYERROR.  |
01421 `-------------------------------------------------------------*/
01422 yyerrlab1:
01423   yyerrstatus = 3;   /* Each real token shifted decrements this.  */
01424 
01425   for (;;)
01426     {
01427       yyn = yypact[yystate];
01428       if (yyn != YYPACT_NINF)
01429    {
01430      yyn += YYTERROR;
01431      if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
01432        {
01433          yyn = yytable[yyn];
01434          if (0 < yyn)
01435       break;
01436        }
01437    }
01438 
01439       /* Pop the current state because it cannot handle the error token.  */
01440       if (yyssp == yyss)
01441    YYABORT;
01442 
01443       yyerror_range[0] = *yylsp;
01444       yydestruct ("Error: popping", yystos[yystate], yyvsp, yylsp);
01445       YYPOPSTACK;
01446       yystate = *yyssp;
01447       YY_STACK_PRINT (yyss, yyssp);
01448     }
01449 
01450   if (yyn == YYFINAL)
01451     YYACCEPT;
01452 
01453   *++yyvsp = yylval;
01454 
01455   yyerror_range[1] = yylloc;
01456   /* Using YYLLOC is tempting, but would change the location of
01457      the look-ahead.  YYLOC is available though. */
01458   YYLLOC_DEFAULT (yyloc, yyerror_range - 1, 2);
01459   *++yylsp = yyloc;
01460 
01461   /* Shift the error token. */
01462   YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
01463 
01464   yystate = yyn;
01465   goto yynewstate;
01466 
01467 
01468 /*-------------------------------------.
01469 | yyacceptlab -- YYACCEPT comes here.  |
01470 `-------------------------------------*/
01471 yyacceptlab:
01472   yyresult = 0;
01473   goto yyreturn;
01474 
01475 /*-----------------------------------.
01476 | yyabortlab -- YYABORT comes here.  |
01477 `-----------------------------------*/
01478 yyabortlab:
01479   yydestruct ("Error: discarding lookahead",
01480               yytoken, &yylval, &yylloc);
01481   yychar = YYEMPTY;
01482   yyresult = 1;
01483   goto yyreturn;
01484 
01485 #ifndef yyoverflow
01486 /*----------------------------------------------.
01487 | yyoverflowlab -- parser overflow comes here.  |
01488 `----------------------------------------------*/
01489 yyoverflowlab:
01490   yyerror ("parser stack overflow");
01491   yyresult = 2;
01492   /* Fall through.  */
01493 #endif
01494 
01495 yyreturn:
01496 #ifndef yyoverflow
01497   if (yyss != yyssa)
01498     YYSTACK_FREE (yyss);
01499 #endif
01500   return yyresult;
01501 }
01502 
01503 
01504 #line 159 "ast_expr.y"
01505 
01506 
01507 static struct val *
01508 make_integer (i)
01509 quad_t i;
01510 {
01511    struct val *vp;
01512 
01513    vp = (struct val *) malloc (sizeof (*vp));
01514    if (vp == NULL) {
01515       ast_log(LOG_WARNING, "malloc() failed\n");
01516       return(NULL);
01517    }
01518 
01519    vp->type = integer;
01520    vp->u.i  = i;
01521    return vp; 
01522 }
01523 
01524 static struct val *
01525 make_str (s)
01526 const char *s;
01527 {
01528    struct val *vp;
01529    size_t i;
01530    int isint;
01531 
01532    vp = (struct val *) malloc (sizeof (*vp));
01533    if (vp == NULL || ((vp->u.s = strdup (s)) == NULL)) {
01534       ast_log(LOG_WARNING,"malloc() failed\n");
01535       return(NULL);
01536    }
01537 
01538    for(i = 1, isint = isdigit(s[0]) || s[0] == '-';
01539        isint && i < strlen(s);
01540        i++)
01541    {
01542       if(!isdigit(s[i]))
01543           isint = 0;
01544    }
01545 
01546    if (isint)
01547       vp->type = numeric_string;
01548    else  
01549       vp->type = string;
01550 
01551    return vp;
01552 }
01553 
01554 
01555 static void
01556 free_value (vp)
01557 struct val *vp;
01558 {  
01559    if (vp==NULL) {
01560       return;
01561    }
01562    if (vp->type == string || vp->type == numeric_string)
01563       free (vp->u.s);   
01564    free (vp);
01565 }
01566 
01567 
01568 static quad_t
01569 to_integer (vp)
01570 struct val *vp;
01571 {
01572    quad_t i;
01573 
01574    if (vp == NULL) {
01575       ast_log(LOG_WARNING,"vp==NULL in to_integer()\n");
01576       return(0);
01577    }
01578 
01579    if (vp->type == integer)
01580       return 1;
01581 
01582    if (vp->type == string)
01583       return 0;
01584 
01585    /* vp->type == numeric_string, make it numeric */
01586    errno = 0;
01587    i  = strtoq(vp->u.s, (char**)NULL, 10);
01588    if (errno != 0) {
01589       free(vp->u.s);
01590       ast_log(LOG_WARNING,"overflow\n");
01591       return(0);
01592    }
01593    free (vp->u.s);
01594    vp->u.i = i;
01595    vp->type = integer;
01596    return 1;
01597 }
01598 
01599 static void
01600 to_string (vp)
01601 struct val *vp;
01602 {
01603    char *tmp;
01604 
01605    if (vp->type == string || vp->type == numeric_string)
01606       return;
01607 
01608    tmp = malloc ((size_t)25);
01609    if (tmp == NULL) {
01610       ast_log(LOG_WARNING,"malloc() failed\n");
01611       return;
01612    }
01613 
01614    sprintf (tmp, "%lld", (long long)vp->u.i);
01615    vp->type = string;
01616    vp->u.s  = tmp;
01617 }
01618 
01619 
01620 static int
01621 isstring (vp)
01622 struct val *vp;
01623 {
01624    /* only TRUE if this string is not a valid integer */
01625    return (vp->type == string);
01626 }
01627 
01628 static int
01629 ast_yylex (YYSTYPE *lvalp, YYLTYPE *yylloc, struct parser_control *karoto)
01630 {
01631    char *p=0;
01632    char *t1=0;
01633    char savep = 0;
01634    char *savepp = 0;
01635    
01636    if (karoto->firsttoken==1) {
01637       t1 = karoto->argv;
01638       karoto->firsttoken = 0;
01639    } else {
01640       t1 = karoto->ptrptr;
01641    }
01642    
01643    while(*t1 && *t1 == ' ' )  /* we can remove worries about leading/multiple spaces being present */
01644       t1++;
01645    karoto->ptrptr = t1;
01646    yylloc->first_column = t1 - karoto->argv;
01647    
01648    while( *t1 && *t1 != ' ' && *t1 != '"') /* find the next space or quote */
01649       t1++;
01650    if( *t1 == ' ' )
01651    {
01652       *t1 = 0;
01653       p = karoto->ptrptr;
01654       karoto->ptrptr = t1+1;
01655       yylloc->last_column = t1 - karoto->argv;
01656    }
01657    else if (*t1 == '"' )
01658    {
01659       /* opening quote. find the closing quote */
01660       char *t2=t1+1;
01661       while( *t2 && *t2 != '"')
01662          t2++;
01663       if( *t2 == '"' )
01664       {
01665          if( *(t2+1) == ' ' || *(t2+1) == 0 )
01666          {
01667             if( *(t2+1) )
01668             {
01669                *(t2+1) = 0;
01670                karoto->ptrptr = t2+2;
01671             }
01672             else
01673             {
01674                karoto->ptrptr = t2+1;
01675             }
01676          }
01677          else
01678          {
01679             /* hmmm. what if another token is here? */
01680             /* maybe we can insert a space? */
01681             savep = *(t2+1);
01682             savepp = t2+1;
01683             *(t2+1) = 0;
01684             karoto->ptrptr = t2+1;
01685          }
01686          p = t1;
01687       }
01688       else
01689       {
01690          /* NOT GOOD -- no closing quote! */
01691          p = t1;
01692          karoto->ptrptr = t2;
01693       }
01694       yylloc->last_column = t2 - karoto->argv;
01695    }
01696    else if( *t1 == 0 )
01697    {
01698       if( t1 != karoto->ptrptr )
01699       {
01700          /* this is the last token */
01701          p = karoto->ptrptr;
01702          karoto->ptrptr = t1;
01703       }
01704       else
01705       {
01706          /* we are done. That was quick */
01707          p = karoto->ptrptr;
01708          yylloc->last_column = t1 - karoto->argv;
01709       }
01710    }
01711    if( *p == 0 )
01712       p = 0;
01713    
01714    if (p==NULL) {
01715       return (0);
01716    }
01717 
01718 
01719    if (strlen (p) == 1) {
01720       if (strchr ("|&=<>+-*/%:()", *p))
01721          return (*p);
01722    } else if (strlen (p) == 2 && p[1] == '=') {
01723       switch (*p) {
01724       case '>': return (GE);
01725       case '<': return (LE);
01726       case '!': return (NE);
01727       }
01728    }
01729 
01730    lvalp->val = make_str (p);
01731    if( savep )
01732    {
01733       *savepp = savep; /* restore the null terminated string */
01734       savepp = 0;
01735       savep = 0;
01736    }
01737    return (TOKEN);
01738 }
01739 
01740 static int
01741 is_zero_or_null (vp)
01742 struct val *vp;
01743 {
01744    if (vp->type == integer) {
01745       return (vp->u.i == 0);
01746    } else {
01747       return (*vp->u.s == 0 || (to_integer (vp) && vp->u.i == 0));
01748    }
01749    /* NOTREACHED */
01750 }
01751 
01752 char *ast_expr (char *arg)
01753 {
01754    struct parser_control karoto;
01755 
01756    char *kota;
01757    char *pirouni;
01758    
01759    kota=strdup(arg);
01760    karoto.result = NULL;
01761    karoto.firsttoken=1;
01762    karoto.argv=kota;
01763    karoto.arg_orig = arg;
01764    /* ast_yydebug = 1; */
01765    
01766    ast_yyparse ((void *)&karoto);
01767 
01768    free(kota);
01769 
01770    if (karoto.result==NULL) {
01771       pirouni=strdup("0");
01772       return(pirouni);
01773    } else {
01774       if (karoto.result->type == integer) {
01775          pirouni=malloc(256);
01776          sprintf (pirouni,"%lld", (long long)karoto.result->u.i);
01777       }
01778       else {
01779          pirouni=strdup(karoto.result->u.s);
01780       }
01781       free(karoto.result);
01782    }
01783    return(pirouni);
01784 }
01785 
01786 #ifdef STANDALONE
01787 
01788 int main(int argc,char **argv) {
01789    char *s;
01790 
01791    s=ast_expr(argv[1]);
01792 
01793    printf("=====%s======\n",s);
01794 }
01795 
01796 #endif
01797 
01798 #undef ast_yyerror
01799 #define ast_yyerror(x) ast_yyerror(x, YYLTYPE *yylloc, struct parser_control *karoto)
01800 
01801 static int
01802 ast_yyerror (const char *s)
01803 {  
01804    char spacebuf[8000]; /* best safe than sorry */
01805    char spacebuf2[8000]; /* best safe than sorry */
01806    int i=0;
01807    spacebuf[0] = 0;
01808    
01809    if( yylloc->first_column > 7990 ) /* if things get out of whack, why crash? */
01810       yylloc->first_column = 7990;
01811    if( yylloc->last_column > 7990 )
01812       yylloc->last_column = 7990;
01813    for(i=0;i<yylloc->first_column;i++) spacebuf[i] = ' ';
01814    for(   ;i<yylloc->last_column;i++) spacebuf[i] = '^';
01815    spacebuf[i] = 0;
01816 
01817    for(i=0;i<karoto->ptrptr-karoto->argv;i++) spacebuf2[i] = ' ';
01818    spacebuf2[i++]='^';
01819    spacebuf2[i]= 0;
01820 
01821    ast_log(LOG_WARNING,"ast_yyerror(): syntax error: %s; Input:\n%s\n%s\n%s\n",s, 
01822          karoto->arg_orig,spacebuf,spacebuf2);
01823    return(0);
01824 }
01825 
01826 
01827 static struct val *
01828 op_or (a, b)
01829 struct val *a, *b;
01830 {
01831    if (is_zero_or_null (a)) {
01832       free_value (a);
01833       return (b);
01834    } else {
01835       free_value (b);
01836       return (a);
01837    }
01838 }
01839       
01840 static struct val *
01841 op_and (a, b)
01842 struct val *a, *b;
01843 {
01844    if (is_zero_or_null (a) || is_zero_or_null (b)) {
01845       free_value (a);
01846       free_value (b);
01847       return (make_integer ((quad_t)0));
01848    } else {
01849       free_value (b);
01850       return (a);
01851    }
01852 }
01853 
01854 static struct val *
01855 op_eq (a, b)
01856 struct val *a, *b;
01857 {
01858    struct val *r; 
01859 
01860    if (isstring (a) || isstring (b)) {
01861       to_string (a);
01862       to_string (b); 
01863       r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) == 0));
01864    } else {
01865       (void)to_integer(a);
01866       (void)to_integer(b);
01867       r = make_integer ((quad_t)(a->u.i == b->u.i));
01868    }
01869 
01870    free_value (a);
01871    free_value (b);
01872    return r;
01873 }
01874 
01875 static struct val *
01876 op_gt (a, b)
01877 struct val *a, *b;
01878 {
01879    struct val *r;
01880 
01881    if (isstring (a) || isstring (b)) {
01882       to_string (a);
01883       to_string (b);
01884       r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) > 0));
01885    } else {
01886       (void)to_integer(a);
01887       (void)to_integer(b);
01888       r = make_integer ((quad_t)(a->u.i > b->u.i));
01889    }
01890 
01891    free_value (a);
01892    free_value (b);
01893    return r;
01894 }
01895 
01896 static struct val *
01897 op_lt (a, b)
01898 struct val *a, *b;
01899 {
01900    struct val *r;
01901 
01902    if (isstring (a) || isstring (b)) {
01903       to_string (a);
01904       to_string (b);
01905       r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) < 0));
01906    } else {
01907       (void)to_integer(a);
01908       (void)to_integer(b);
01909       r = make_integer ((quad_t)(a->u.i < b->u.i));
01910    }
01911 
01912    free_value (a);
01913    free_value (b);
01914    return r;
01915 }
01916 
01917 static struct val *
01918 op_ge (a, b)
01919 struct val *a, *b;
01920 {
01921    struct val *r;
01922 
01923    if (isstring (a) || isstring (b)) {
01924       to_string (a);
01925       to_string (b);
01926       r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) >= 0));
01927    } else {
01928       (void)to_integer(a);
01929       (void)to_integer(b);
01930       r = make_integer ((quad_t)(a->u.i >= b->u.i));
01931    }
01932 
01933    free_value (a);
01934    free_value (b);
01935    return r;
01936 }
01937 
01938 static struct val *
01939 op_le (a, b)
01940 struct val *a, *b;
01941 {
01942    struct val *r;
01943 
01944    if (isstring (a) || isstring (b)) {
01945       to_string (a);
01946       to_string (b);
01947       r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) <= 0));
01948    } else {
01949       (void)to_integer(a);
01950       (void)to_integer(b);
01951       r = make_integer ((quad_t)(a->u.i <= b->u.i));
01952    }
01953 
01954    free_value (a);
01955    free_value (b);
01956    return r;
01957 }
01958 
01959 static struct val *
01960 op_ne (a, b)
01961 struct val *a, *b;
01962 {
01963    struct val *r;
01964 
01965    if (isstring (a) || isstring (b)) {
01966       to_string (a);
01967       to_string (b);
01968       r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) != 0));
01969    } else {
01970       (void)to_integer(a);
01971       (void)to_integer(b);
01972       r = make_integer ((quad_t)(a->u.i != b->u.i));
01973    }
01974 
01975    free_value (a);
01976    free_value (b);
01977    return r;
01978 }
01979 
01980 static int
01981 chk_plus (a, b, r)
01982 quad_t a, b, r;
01983 {
01984    /* sum of two positive numbers must be positive */
01985    if (a > 0 && b > 0 && r <= 0)
01986       return 1;
01987    /* sum of two negative numbers must be negative */
01988    if (a < 0 && b < 0 && r >= 0)
01989       return 1;
01990    /* all other cases are OK */
01991    return 0;
01992 }
01993 
01994 static struct val *
01995 op_plus (a, b)
01996 struct val *a, *b;
01997 {
01998    struct val *r;
01999 
02000    if (!to_integer (a)) {
02001       ast_log(LOG_WARNING,"non-numeric argument\n");
02002       if (!to_integer (b)) {
02003          free_value(a);
02004          free_value(b);
02005          return make_integer(0);
02006       } else {
02007          free_value(a);
02008          return (b);
02009       }
02010    } else if (!to_integer(b)) {
02011       free_value(b);
02012       return (a);
02013    }
02014 
02015    r = make_integer (/*(quad_t)*/(a->u.i + b->u.i));
02016    if (chk_plus (a->u.i, b->u.i, r->u.i)) {
02017       ast_log(LOG_WARNING,"overflow\n");
02018    }
02019    free_value (a);
02020    free_value (b);
02021    return r;
02022 }
02023 
02024 static int
02025 chk_minus (a, b, r)
02026 quad_t a, b, r;
02027 {
02028    /* special case subtraction of QUAD_MIN */
02029    if (b == QUAD_MIN) {
02030       if (a >= 0)
02031          return 1;
02032       else
02033          return 0;
02034    }
02035    /* this is allowed for b != QUAD_MIN */
02036    return chk_plus (a, -b, r);
02037 }
02038 
02039 static struct val *
02040 op_minus (a, b)
02041 struct val *a, *b;
02042 {
02043    struct val *r;
02044 
02045    if (!to_integer (a)) {
02046       ast_log(LOG_WARNING, "non-numeric argument\n");
02047       if (!to_integer (b)) {
02048          free_value(a);
02049          free_value(b);
02050          return make_integer(0);
02051       } else {
02052          r = make_integer(0 - b->u.i);
02053          free_value(a);
02054          free_value(b);
02055          return (r);
02056       }
02057    } else if (!to_integer(b)) {
02058       ast_log(LOG_WARNING, "non-numeric argument\n");
02059       free_value(b);
02060       return (a);
02061    }
02062 
02063    r = make_integer (/*(quad_t)*/(a->u.i - b->u.i));
02064    if (chk_minus (a->u.i, b->u.i, r->u.i)) {
02065       ast_log(LOG_WARNING, "overflow\n");
02066    }
02067    free_value (a);
02068    free_value (b);
02069    return r;
02070 }
02071 
02072 static int
02073 chk_times (a, b, r)
02074 quad_t a, b, r;
02075 {
02076    /* special case: first operand is 0, no overflow possible */
02077    if (a == 0)
02078       return 0;
02079    /* cerify that result of division matches second operand */
02080    if (r / a != b)
02081       return 1;
02082    return 0;
02083 }
02084 
02085 static struct val *
02086 op_times (a, b)
02087 struct val *a, *b;
02088 {
02089    struct val *r;
02090 
02091    if (!to_integer (a) || !to_integer (b)) {
02092       free_value(a);
02093       free_value(b);
02094       ast_log(LOG_WARNING, "non-numeric argument\n");
02095       return(make_integer(0));
02096    }
02097 
02098    r = make_integer (/*(quad_t)*/(a->u.i * b->u.i));
02099    if (chk_times (a->u.i, b->u.i, r->u.i)) {
02100       ast_log(LOG_WARNING, "overflow\n");
02101    }
02102    free_value (a);
02103    free_value (b);
02104    return (r);
02105 }
02106 
02107 static int
02108 chk_div (a, b)
02109 quad_t a, b;
02110 {
02111    /* div by zero has been taken care of before */
02112    /* only QUAD_MIN / -1 causes overflow */
02113    if (a == QUAD_MIN && b == -1)
02114       return 1;
02115    /* everything else is OK */
02116    return 0;
02117 }
02118 
02119 static struct val *
02120 op_div (a, b)
02121 struct val *a, *b;
02122 {
02123    struct val *r;
02124 
02125    if (!to_integer (a)) {
02126       free_value(a);
02127       free_value(b);
02128       ast_log(LOG_WARNING, "non-numeric argument\n");
02129       return make_integer(0);
02130    } else if (!to_integer (b)) {
02131       free_value(a);
02132       free_value(b);
02133       ast_log(LOG_WARNING, "non-numeric argument\n");
02134       return make_integer(INT_MAX);
02135    }
02136 
02137    if (b->u.i == 0) {
02138       ast_log(LOG_WARNING, "division by zero\n");     
02139       free_value(a);
02140       free_value(b);
02141       return make_integer(INT_MAX);
02142    }
02143 
02144    r = make_integer (/*(quad_t)*/(a->u.i / b->u.i));
02145    if (chk_div (a->u.i, b->u.i)) {
02146       ast_log(LOG_WARNING, "overflow\n");
02147    }
02148    free_value (a);
02149    free_value (b);
02150    return r;
02151 }
02152    
02153 static struct val *
02154 op_rem (a, b)
02155 struct val *a, *b;
02156 {
02157    struct val *r;
02158 
02159    if (!to_integer (a) || !to_integer (b)) {
02160       ast_log(LOG_WARNING, "non-numeric argument\n");
02161       free_value(a);
02162       free_value(b);
02163       return make_integer(0);
02164    }
02165 
02166    if (b->u.i == 0) {
02167       ast_log(LOG_WARNING, "div by zero\n");
02168       free_value(a);
02169       return (b);
02170    }
02171 
02172    r = make_integer (/*(quad_t)*/(a->u.i % b->u.i));
02173    /* chk_rem necessary ??? */
02174    free_value (a);
02175    free_value (b);
02176    return r;
02177 }
02178    
02179 static struct val *
02180 op_colon (a, b)
02181 struct val *a, *b;
02182 {
02183    regex_t rp;
02184    regmatch_t rm[2];
02185    char errbuf[256];
02186    int eval;
02187    struct val *v;
02188 
02189    /* coerce to both arguments to strings */
02190    to_string(a);
02191    to_string(b);
02192 
02193    /* compile regular expression */
02194    if ((eval = regcomp (&rp, b->u.s, REG_EXTENDED)) != 0) {
02195       regerror (eval, &rp, errbuf, sizeof(errbuf));
02196       ast_log(LOG_WARNING,"regcomp() error : %s",errbuf);
02197       free_value(a);
02198       free_value(b);
02199       return make_str("");    
02200    }
02201 
02202    /* compare string against pattern */
02203    /* remember that patterns are anchored to the beginning of the line */
02204    if (regexec(&rp, a->u.s, (size_t)2, rm, 0) == 0 && rm[0].rm_so == 0) {
02205       if (rm[1].rm_so >= 0) {
02206          *(a->u.s + rm[1].rm_eo) = '\0';
02207          v = make_str (a->u.s + rm[1].rm_so);
02208 
02209       } else {
02210          v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so));
02211       }
02212    } else {
02213       if (rp.re_nsub == 0) {
02214          v = make_integer ((quad_t)0);
02215       } else {
02216          v = make_str ("");
02217       }
02218    }
02219 
02220    /* free arguments and pattern buffer */
02221    free_value (a);
02222    free_value (b);
02223    regfree (&rp);
02224 
02225    return v;
02226 }
02227 
02228 

Generated on Wed Aug 10 11:36:31 2005 for Asterisk by  doxygen 1.4.4