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

ast_expr.c

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

Generated on Tue Aug 17 16:13:52 2004 for Asterisk by doxygen 1.3.8