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

Generated on Thu Nov 29 22:50:22 2007 for Asterisk by  doxygen 1.4.2