00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #define YYBISON 1
00038
00039
00040 #define YYSKELETON_NAME "yacc.c"
00041
00042
00043 #define YYPURE 1
00044
00045
00046 #define YYLSP_NEEDED 0
00047
00048
00049
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
00058
00059
00060 #ifndef YYTOKENTYPE
00061 # define YYTOKENTYPE
00062
00063
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
00080 #line 1 "ast_expr.y"
00081
00082
00083
00084
00085
00086
00087
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 # if ! defined(QUAD_MIN)
00104 # define QUAD_MIN (-0x7fffffffffffffffL-1)
00105 # endif
00106 # if ! defined(QUAD_MAX)
00107 # define QUAD_MAX (0x7fffffffffffffffL)
00108 # endif
00109
00110 #define YYPARSE_PARAM kota
00111 #define YYLEX_PARAM kota
00112
00113
00114
00115
00116 enum valtype {
00117 integer, numeric_string, string
00118 } ;
00119
00120 struct val {
00121 enum valtype type;
00122 union {
00123 char *s;
00124 quad_t i;
00125 } u;
00126 } ;
00127
00128 struct parser_control {
00129 struct val *result;
00130 int pipa;
00131 char *argv;
00132 char *ptrptr;
00133 int firsttoken;
00134 } ;
00135
00136 static int chk_div __P((quad_t, quad_t));
00137 static int chk_minus __P((quad_t, quad_t, quad_t));
00138 static int chk_plus __P((quad_t, quad_t, quad_t));
00139 static int chk_times __P((quad_t, quad_t, quad_t));
00140 static void free_value __P((struct val *));
00141 static int is_zero_or_null __P((struct val *));
00142 static int isstring __P((struct val *));
00143 static struct val *make_integer __P((quad_t));
00144 static struct val *make_str __P((const char *));
00145 static struct val *op_and __P((struct val *, struct val *));
00146 static struct val *op_colon __P((struct val *, struct val *));
00147 static struct val *op_div __P((struct val *, struct val *));
00148 static struct val *op_eq __P((struct val *, struct val *));
00149 static struct val *op_ge __P((struct val *, struct val *));
00150 static struct val *op_gt __P((struct val *, struct val *));
00151 static struct val *op_le __P((struct val *, struct val *));
00152 static struct val *op_lt __P((struct val *, struct val *));
00153 static struct val *op_minus __P((struct val *, struct val *));
00154 static struct val *op_ne __P((struct val *, struct val *));
00155 static struct val *op_or __P((struct val *, struct val *));
00156 static struct val *op_plus __P((struct val *, struct val *));
00157 static struct val *op_rem __P((struct val *, struct val *));
00158 static struct val *op_times __P((struct val *, struct val *));
00159 static quad_t to_integer __P((struct val *));
00160 static void to_string __P((struct val *));
00161 static int ast_yyerror __P((const char *));
00162 static int ast_yylex __P(());
00163
00164
00165
00166 #ifndef YYDEBUG
00167 # define YYDEBUG 0
00168 #endif
00169
00170
00171 #ifdef YYERROR_VERBOSE
00172 # undef YYERROR_VERBOSE
00173 # define YYERROR_VERBOSE 1
00174 #else
00175 # define YYERROR_VERBOSE 0
00176 #endif
00177
00178 #if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
00179 #line 90 "ast_expr.y"
00180 typedef union YYSTYPE {
00181 struct val *val;
00182 } YYSTYPE;
00183
00184 #line 185 "ast_expr.c"
00185 # define yystype YYSTYPE
00186 # define YYSTYPE_IS_DECLARED 1
00187 # define YYSTYPE_IS_TRIVIAL 1
00188 #endif
00189
00190
00191
00192
00193
00194
00195
00196 #line 197 "ast_expr.c"
00197
00198 #if ! defined (yyoverflow) || YYERROR_VERBOSE
00199
00200
00201
00202 # if YYSTACK_USE_ALLOCA
00203 # define YYSTACK_ALLOC alloca
00204 # else
00205 # ifndef YYSTACK_USE_ALLOCA
00206 # if defined (alloca) || defined (_ALLOCA_H)
00207 # define YYSTACK_ALLOC alloca
00208 # else
00209 # ifdef __GNUC__
00210 # define YYSTACK_ALLOC __builtin_alloca
00211 # endif
00212 # endif
00213 # endif
00214 # endif
00215
00216 # ifdef YYSTACK_ALLOC
00217
00218 # define YYSTACK_FREE(Ptr) do { ; } while (0)
00219 # else
00220 # if defined (__STDC__) || defined (__cplusplus)
00221 # include <stdlib.h>
00222 # define YYSIZE_T size_t
00223 # endif
00224 # define YYSTACK_ALLOC malloc
00225 # define YYSTACK_FREE free
00226 # endif
00227 #endif
00228
00229
00230 #if (! defined (yyoverflow) \
00231 && (! defined (__cplusplus) \
00232 || (YYSTYPE_IS_TRIVIAL)))
00233
00234
00235 union yyalloc
00236 {
00237 short yyss;
00238 YYSTYPE yyvs;
00239 };
00240
00241
00242 # define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
00243
00244
00245
00246 # define YYSTACK_BYTES(N) \
00247 ((N) * (sizeof (short) + sizeof (YYSTYPE)) \
00248 + YYSTACK_GAP_MAXIMUM)
00249
00250
00251
00252 # ifndef YYCOPY
00253 # if 1 < __GNUC__
00254 # define YYCOPY(To, From, Count) \
00255 __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
00256 # else
00257 # define YYCOPY(To, From, Count) \
00258 do \
00259 { \
00260 register YYSIZE_T yyi; \
00261 for (yyi = 0; yyi < (Count); yyi++) \
00262 (To)[yyi] = (From)[yyi]; \
00263 } \
00264 while (0)
00265 # endif
00266 # endif
00267
00268
00269
00270
00271
00272
00273 # define YYSTACK_RELOCATE(Stack) \
00274 do \
00275 { \
00276 YYSIZE_T yynewbytes; \
00277 YYCOPY (&yyptr->Stack, Stack, yysize); \
00278 Stack = &yyptr->Stack; \
00279 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
00280 yyptr += yynewbytes / sizeof (*yyptr); \
00281 } \
00282 while (0)
00283
00284 #endif
00285
00286 #if defined (__STDC__) || defined (__cplusplus)
00287 typedef signed char yysigned_char;
00288 #else
00289 typedef short yysigned_char;
00290 #endif
00291
00292
00293 #define YYFINAL 6
00294
00295 #define YYLAST 83
00296
00297
00298 #define YYNTOKENS 20
00299
00300 #define YYNNTS 3
00301
00302 #define YYNRULES 18
00303
00304 #define YYNSTATES 36
00305
00306
00307 #define YYUNDEFTOK 2
00308 #define YYMAXUTOK 261
00309
00310 #define YYTRANSLATE(YYX) \
00311 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
00312
00313
00314 static const unsigned char yytranslate[] =
00315 {
00316 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00317 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00318 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00319 2, 2, 2, 2, 2, 2, 2, 15, 4, 2,
00320 18, 19, 13, 11, 2, 12, 2, 14, 2, 2,
00321 2, 2, 2, 2, 2, 2, 2, 2, 16, 2,
00322 7, 5, 6, 2, 2, 2, 2, 2, 2, 2,
00323 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00324 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00325 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00326 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00327 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00328 2, 2, 2, 2, 3, 2, 2, 2, 2, 2,
00329 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00330 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00331 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00332 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00333 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00334 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00335 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00336 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00337 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00338 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00339 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00340 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
00341 2, 2, 2, 2, 2, 2, 1, 2, 8, 9,
00342 10, 17
00343 };
00344
00345 #if YYDEBUG
00346
00347
00348 static const unsigned char yyprhs[] =
00349 {
00350 0, 0, 3, 5, 7, 11, 15, 19, 23, 27,
00351 31, 35, 39, 43, 47, 51, 55, 59, 63
00352 };
00353
00354
00355 static const yysigned_char yyrhs[] =
00356 {
00357 21, 0, -1, 22, -1, 17, -1, 18, 22, 19,
00358 -1, 22, 3, 22, -1, 22, 4, 22, -1, 22,
00359 5, 22, -1, 22, 6, 22, -1, 22, 7, 22,
00360 -1, 22, 10, 22, -1, 22, 9, 22, -1, 22,
00361 8, 22, -1, 22, 11, 22, -1, 22, 12, 22,
00362 -1, 22, 13, 22, -1, 22, 14, 22, -1, 22,
00363 15, 22, -1, 22, 16, 22, -1
00364 };
00365
00366
00367 static const unsigned char yyrline[] =
00368 {
00369 0, 106, 106, 109, 110, 111, 112, 113, 114, 115,
00370 116, 117, 118, 119, 120, 121, 122, 123, 124
00371 };
00372 #endif
00373
00374 #if YYDEBUG || YYERROR_VERBOSE
00375
00376
00377 static const char *const yytname[] =
00378 {
00379 "$end", "error", "$undefined", "'|'", "'&'", "'='", "'>'", "'<'", "NE",
00380 "LE", "GE", "'+'", "'-'", "'*'", "'/'", "'%'", "':'", "TOKEN", "'('",
00381 "')'", "$accept", "start", "expr", 0
00382 };
00383 #endif
00384
00385 # ifdef YYPRINT
00386
00387
00388 static const unsigned short yytoknum[] =
00389 {
00390 0, 256, 257, 124, 38, 61, 62, 60, 258, 259,
00391 260, 43, 45, 42, 47, 37, 58, 261, 40, 41
00392 };
00393 # endif
00394
00395
00396 static const unsigned char yyr1[] =
00397 {
00398 0, 20, 21, 22, 22, 22, 22, 22, 22, 22,
00399 22, 22, 22, 22, 22, 22, 22, 22, 22
00400 };
00401
00402
00403 static const unsigned char yyr2[] =
00404 {
00405 0, 2, 1, 1, 3, 3, 3, 3, 3, 3,
00406 3, 3, 3, 3, 3, 3, 3, 3, 3
00407 };
00408
00409
00410
00411
00412 static const unsigned char yydefact[] =
00413 {
00414 0, 3, 0, 0, 2, 0, 1, 0, 0, 0,
00415 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
00416 0, 4, 5, 6, 7, 8, 9, 12, 11, 10,
00417 13, 14, 15, 16, 17, 18
00418 };
00419
00420
00421 static const yysigned_char yydefgoto[] =
00422 {
00423 -1, 3, 4
00424 };
00425
00426
00427
00428 #define YYPACT_NINF -13
00429 static const yysigned_char yypact[] =
00430 {
00431 65, -13, 65, 34, 33, 16, -13, 65, 65, 65,
00432 65, 65, 65, 65, 65, 65, 65, 65, 65, 65,
00433 65, -13, 46, 58, 64, 64, 64, 64, 64, 64,
00434 -12, -12, 17, 17, 17, -13
00435 };
00436
00437
00438 static const yysigned_char yypgoto[] =
00439 {
00440 -13, -13, -2
00441 };
00442
00443
00444
00445
00446
00447 #define YYTABLE_NINF -1
00448 static const unsigned char yytable[] =
00449 {
00450 5, 17, 18, 19, 20, 22, 23, 24, 25, 26,
00451 27, 28, 29, 30, 31, 32, 33, 34, 35, 7,
00452 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
00453 18, 19, 20, 20, 6, 21, 7, 8, 9, 10,
00454 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
00455 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
00456 18, 19, 20, 9, 10, 11, 12, 13, 14, 15,
00457 16, 17, 18, 19, 20, 15, 16, 17, 18, 19,
00458 20, 0, 1, 2
00459 };
00460
00461 static const yysigned_char yycheck[] =
00462 {
00463 2, 13, 14, 15, 16, 7, 8, 9, 10, 11,
00464 12, 13, 14, 15, 16, 17, 18, 19, 20, 3,
00465 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
00466 14, 15, 16, 16, 0, 19, 3, 4, 5, 6,
00467 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
00468 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
00469 14, 15, 16, 5, 6, 7, 8, 9, 10, 11,
00470 12, 13, 14, 15, 16, 11, 12, 13, 14, 15,
00471 16, -1, 17, 18
00472 };
00473
00474
00475
00476 static const unsigned char yystos[] =
00477 {
00478 0, 17, 18, 21, 22, 22, 0, 3, 4, 5,
00479 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
00480 16, 19, 22, 22, 22, 22, 22, 22, 22, 22,
00481 22, 22, 22, 22, 22, 22
00482 };
00483
00484 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
00485 # define YYSIZE_T __SIZE_TYPE__
00486 #endif
00487 #if ! defined (YYSIZE_T) && defined (size_t)
00488 # define YYSIZE_T size_t
00489 #endif
00490 #if ! defined (YYSIZE_T)
00491 # if defined (__STDC__) || defined (__cplusplus)
00492 # include <stddef.h>
00493 # define YYSIZE_T size_t
00494 # endif
00495 #endif
00496 #if ! defined (YYSIZE_T)
00497 # define YYSIZE_T unsigned int
00498 #endif
00499
00500 #define yyerrok (yyerrstatus = 0)
00501 #define yyclearin (yychar = YYEMPTY)
00502 #define YYEMPTY (-2)
00503 #define YYEOF 0
00504
00505 #define YYACCEPT goto yyacceptlab
00506 #define YYABORT goto yyabortlab
00507 #define YYERROR goto yyerrlab1
00508
00509
00510
00511
00512
00513
00514 #define YYFAIL goto yyerrlab
00515
00516 #define YYRECOVERING() (!!yyerrstatus)
00517
00518 #define YYBACKUP(Token, Value) \
00519 do \
00520 if (yychar == YYEMPTY && yylen == 1) \
00521 { \
00522 yychar = (Token); \
00523 yylval = (Value); \
00524 yytoken = YYTRANSLATE (yychar); \
00525 YYPOPSTACK; \
00526 goto yybackup; \
00527 } \
00528 else \
00529 { \
00530 yyerror ("syntax error: cannot back up");\
00531 YYERROR; \
00532 } \
00533 while (0)
00534
00535 #define YYTERROR 1
00536 #define YYERRCODE 256
00537
00538
00539
00540
00541 #ifndef YYLLOC_DEFAULT
00542 # define YYLLOC_DEFAULT(Current, Rhs, N) \
00543 Current.first_line = Rhs[1].first_line; \
00544 Current.first_column = Rhs[1].first_column; \
00545 Current.last_line = Rhs[N].last_line; \
00546 Current.last_column = Rhs[N].last_column;
00547 #endif
00548
00549
00550
00551 #ifdef YYLEX_PARAM
00552 # define YYLEX yylex (&yylval, YYLEX_PARAM)
00553 #else
00554 # define YYLEX yylex (&yylval)
00555 #endif
00556
00557
00558 #if YYDEBUG
00559
00560 # ifndef YYFPRINTF
00561 # include <stdio.h>
00562 # define YYFPRINTF fprintf
00563 # endif
00564
00565 # define YYDPRINTF(Args) \
00566 do { \
00567 if (yydebug) \
00568 YYFPRINTF Args; \
00569 } while (0)
00570
00571 # define YYDSYMPRINT(Args) \
00572 do { \
00573 if (yydebug) \
00574 yysymprint Args; \
00575 } while (0)
00576
00577 # define YYDSYMPRINTF(Title, Token, Value, Location) \
00578 do { \
00579 if (yydebug) \
00580 { \
00581 YYFPRINTF (stderr, "%s ", Title); \
00582 yysymprint (stderr, \
00583 Token, Value); \
00584 YYFPRINTF (stderr, "\n"); \
00585 } \
00586 } while (0)
00587
00588
00589
00590
00591
00592
00593 #if defined (__STDC__) || defined (__cplusplus)
00594 static void
00595 yy_stack_print (short *bottom, short *top)
00596 #else
00597 static void
00598 yy_stack_print (bottom, top)
00599 short *bottom;
00600 short *top;
00601 #endif
00602 {
00603 YYFPRINTF (stderr, "Stack now");
00604 for (; bottom <= top; ++bottom)
00605 YYFPRINTF (stderr, " %d", *bottom);
00606 YYFPRINTF (stderr, "\n");
00607 }
00608
00609 # define YY_STACK_PRINT(Bottom, Top) \
00610 do { \
00611 if (yydebug) \
00612 yy_stack_print ((Bottom), (Top)); \
00613 } while (0)
00614
00615
00616
00617
00618
00619
00620 #if defined (__STDC__) || defined (__cplusplus)
00621 static void
00622 yy_reduce_print (int yyrule)
00623 #else
00624 static void
00625 yy_reduce_print (yyrule)
00626 int yyrule;
00627 #endif
00628 {
00629 int yyi;
00630 unsigned int yylineno = yyrline[yyrule];
00631 YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
00632 yyrule - 1, yylineno);
00633
00634 for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
00635 YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
00636 YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
00637 }
00638
00639 # define YY_REDUCE_PRINT(Rule) \
00640 do { \
00641 if (yydebug) \
00642 yy_reduce_print (Rule); \
00643 } while (0)
00644
00645
00646
00647 int yydebug;
00648 #else
00649 # define YYDPRINTF(Args)
00650 # define YYDSYMPRINT(Args)
00651 # define YYDSYMPRINTF(Title, Token, Value, Location)
00652 # define YY_STACK_PRINT(Bottom, Top)
00653 # define YY_REDUCE_PRINT(Rule)
00654 #endif
00655
00656
00657
00658 #ifndef YYINITDEPTH
00659 # define YYINITDEPTH 200
00660 #endif
00661
00662
00663
00664
00665
00666
00667
00668
00669 #if YYMAXDEPTH == 0
00670 # undef YYMAXDEPTH
00671 #endif
00672
00673 #ifndef YYMAXDEPTH
00674 # define YYMAXDEPTH 10000
00675 #endif
00676
00677
00678
00679 #if YYERROR_VERBOSE
00680
00681 # ifndef yystrlen
00682 # if defined (__GLIBC__) && defined (_STRING_H)
00683 # define yystrlen strlen
00684 # else
00685
00686 static YYSIZE_T
00687 # if defined (__STDC__) || defined (__cplusplus)
00688 yystrlen (const char *yystr)
00689 # else
00690 yystrlen (yystr)
00691 const char *yystr;
00692 # endif
00693 {
00694 register const char *yys = yystr;
00695
00696 while (*yys++ != '\0')
00697 continue;
00698
00699 return yys - yystr - 1;
00700 }
00701 # endif
00702 # endif
00703
00704 # ifndef yystpcpy
00705 # if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
00706 # define yystpcpy stpcpy
00707 # else
00708
00709
00710 static char *
00711 # if defined (__STDC__) || defined (__cplusplus)
00712 yystpcpy (char *yydest, const char *yysrc)
00713 # else
00714 yystpcpy (yydest, yysrc)
00715 char *yydest;
00716 const char *yysrc;
00717 # endif
00718 {
00719 register char *yyd = yydest;
00720 register const char *yys = yysrc;
00721
00722 while ((*yyd++ = *yys++) != '\0')
00723 continue;
00724
00725 return yyd - 1;
00726 }
00727 # endif
00728 # endif
00729
00730 #endif
00731
00732
00733
00734 #if YYDEBUG
00735
00736
00737
00738
00739 #if defined (__STDC__) || defined (__cplusplus)
00740 static void
00741 yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
00742 #else
00743 static void
00744 yysymprint (yyoutput, yytype, yyvaluep)
00745 FILE *yyoutput;
00746 int yytype;
00747 YYSTYPE *yyvaluep;
00748 #endif
00749 {
00750
00751 (void) yyvaluep;
00752
00753 if (yytype < YYNTOKENS)
00754 {
00755 YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
00756 # ifdef YYPRINT
00757 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
00758 # endif
00759 }
00760 else
00761 YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
00762
00763 switch (yytype)
00764 {
00765 default:
00766 break;
00767 }
00768 YYFPRINTF (yyoutput, ")");
00769 }
00770
00771 #endif
00772
00773
00774
00775
00776 #if defined (__STDC__) || defined (__cplusplus)
00777 static void
00778 yydestruct (int yytype, YYSTYPE *yyvaluep)
00779 #else
00780 static void
00781 yydestruct (yytype, yyvaluep)
00782 int yytype;
00783 YYSTYPE *yyvaluep;
00784 #endif
00785 {
00786
00787 (void) yyvaluep;
00788
00789 switch (yytype)
00790 {
00791
00792 default:
00793 break;
00794 }
00795 }
00796
00797
00798
00799
00800 #ifdef YYPARSE_PARAM
00801 # if defined (__STDC__) || defined (__cplusplus)
00802 int yyparse (void *YYPARSE_PARAM);
00803 # else
00804 int yyparse ();
00805 # endif
00806 #else
00807 #if defined (__STDC__) || defined (__cplusplus)
00808 int yyparse (void);
00809 #else
00810 int yyparse ();
00811 #endif
00812 #endif
00813
00814
00815
00816
00817
00818
00819
00820
00821
00822
00823 #ifdef YYPARSE_PARAM
00824 # if defined (__STDC__) || defined (__cplusplus)
00825 int yyparse (void *YYPARSE_PARAM)
00826 # else
00827 int yyparse (YYPARSE_PARAM)
00828 void *YYPARSE_PARAM;
00829 # endif
00830 #else
00831 #if defined (__STDC__) || defined (__cplusplus)
00832 int
00833 yyparse (void)
00834 #else
00835 int
00836 yyparse ()
00837
00838 #endif
00839 #endif
00840 {
00841
00842 int yychar;
00843
00844
00845 YYSTYPE yylval;
00846
00847
00848 int yynerrs;
00849
00850 register int yystate;
00851 register int yyn;
00852 int yyresult;
00853
00854 int yyerrstatus;
00855
00856 int yytoken = 0;
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867 short yyssa[YYINITDEPTH];
00868 short *yyss = yyssa;
00869 register short *yyssp;
00870
00871
00872 YYSTYPE yyvsa[YYINITDEPTH];
00873 YYSTYPE *yyvs = yyvsa;
00874 register YYSTYPE *yyvsp;
00875
00876
00877
00878 #define YYPOPSTACK (yyvsp--, yyssp--)
00879
00880 YYSIZE_T yystacksize = YYINITDEPTH;
00881
00882
00883
00884 YYSTYPE yyval;
00885
00886
00887
00888
00889 int yylen;
00890
00891 YYDPRINTF ((stderr, "Starting parse\n"));
00892
00893 yystate = 0;
00894 yyerrstatus = 0;
00895 yynerrs = 0;
00896 yychar = YYEMPTY;
00897
00898
00899
00900
00901
00902
00903 yyssp = yyss;
00904 yyvsp = yyvs;
00905
00906 goto yysetstate;
00907
00908
00909
00910
00911 yynewstate:
00912
00913
00914
00915 yyssp++;
00916
00917 yysetstate:
00918 *yyssp = yystate;
00919
00920 if (yyss + yystacksize - 1 <= yyssp)
00921 {
00922
00923 YYSIZE_T yysize = yyssp - yyss + 1;
00924
00925 #ifdef yyoverflow
00926 {
00927
00928
00929
00930 YYSTYPE *yyvs1 = yyvs;
00931 short *yyss1 = yyss;
00932
00933
00934
00935
00936
00937
00938 yyoverflow ("parser stack overflow",
00939 &yyss1, yysize * sizeof (*yyssp),
00940 &yyvs1, yysize * sizeof (*yyvsp),
00941
00942 &yystacksize);
00943
00944 yyss = yyss1;
00945 yyvs = yyvs1;
00946 }
00947 #else
00948 # ifndef YYSTACK_RELOCATE
00949 goto yyoverflowlab;
00950 # else
00951
00952 if (YYMAXDEPTH <= yystacksize)
00953 goto yyoverflowlab;
00954 yystacksize *= 2;
00955 if (YYMAXDEPTH < yystacksize)
00956 yystacksize = YYMAXDEPTH;
00957
00958 {
00959 short *yyss1 = yyss;
00960 union yyalloc *yyptr =
00961 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
00962 if (! yyptr)
00963 goto yyoverflowlab;
00964 YYSTACK_RELOCATE (yyss);
00965 YYSTACK_RELOCATE (yyvs);
00966
00967 # undef YYSTACK_RELOCATE
00968 if (yyss1 != yyssa)
00969 YYSTACK_FREE (yyss1);
00970 }
00971 # endif
00972 #endif
00973
00974 yyssp = yyss + yysize - 1;
00975 yyvsp = yyvs + yysize - 1;
00976
00977
00978 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
00979 (unsigned long int) yystacksize));
00980
00981 if (yyss + yystacksize - 1 <= yyssp)
00982 YYABORT;
00983 }
00984
00985 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
00986
00987 goto yybackup;
00988
00989
00990
00991
00992 yybackup:
00993
00994
00995
00996
00997
00998
00999
01000 yyn = yypact[yystate];
01001 if (yyn == YYPACT_NINF)
01002 goto yydefault;
01003
01004
01005
01006
01007 if (yychar == YYEMPTY)
01008 {
01009 YYDPRINTF ((stderr, "Reading a token: "));
01010 yychar = YYLEX;
01011 }
01012
01013 if (yychar <= YYEOF)
01014 {
01015 yychar = yytoken = YYEOF;
01016 YYDPRINTF ((stderr, "Now at end of input.\n"));
01017 }
01018 else
01019 {
01020 yytoken = YYTRANSLATE (yychar);
01021 YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
01022 }
01023
01024
01025
01026 yyn += yytoken;
01027 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
01028 goto yydefault;
01029 yyn = yytable[yyn];
01030 if (yyn <= 0)
01031 {
01032 if (yyn == 0 || yyn == YYTABLE_NINF)
01033 goto yyerrlab;
01034 yyn = -yyn;
01035 goto yyreduce;
01036 }
01037
01038 if (yyn == YYFINAL)
01039 YYACCEPT;
01040
01041
01042 YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));
01043
01044
01045 if (yychar != YYEOF)
01046 yychar = YYEMPTY;
01047
01048 *++yyvsp = yylval;
01049
01050
01051
01052
01053 if (yyerrstatus)
01054 yyerrstatus--;
01055
01056 yystate = yyn;
01057 goto yynewstate;
01058
01059
01060
01061
01062
01063 yydefault:
01064 yyn = yydefact[yystate];
01065 if (yyn == 0)
01066 goto yyerrlab;
01067 goto yyreduce;
01068
01069
01070
01071
01072
01073 yyreduce:
01074
01075 yylen = yyr2[yyn];
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085 yyval = yyvsp[1-yylen];
01086
01087
01088 YY_REDUCE_PRINT (yyn);
01089 switch (yyn)
01090 {
01091 case 2:
01092 #line 106 "ast_expr.y"
01093 { ((struct parser_control *)kota)->result = yyval.val; ;}
01094 break;
01095
01096 case 4:
01097 #line 110 "ast_expr.y"
01098 { yyval.val = yyvsp[-1].val; ;}
01099 break;
01100
01101 case 5:
01102 #line 111 "ast_expr.y"
01103 { yyval.val = op_or (yyvsp[-2].val, yyvsp[0].val); ;}
01104 break;
01105
01106 case 6:
01107 #line 112 "ast_expr.y"
01108 { yyval.val = op_and (yyvsp[-2].val, yyvsp[0].val); ;}
01109 break;
01110
01111 case 7:
01112 #line 113 "ast_expr.y"
01113 { yyval.val = op_eq (yyvsp[-2].val, yyvsp[0].val); ;}
01114 break;
01115
01116 case 8:
01117 #line 114 "ast_expr.y"
01118 { yyval.val = op_gt (yyvsp[-2].val, yyvsp[0].val); ;}
01119 break;
01120
01121 case 9:
01122 #line 115 "ast_expr.y"
01123 { yyval.val = op_lt (yyvsp[-2].val, yyvsp[0].val); ;}
01124 break;
01125
01126 case 10:
01127 #line 116 "ast_expr.y"
01128 { yyval.val = op_ge (yyvsp[-2].val, yyvsp[0].val); ;}
01129 break;
01130
01131 case 11:
01132 #line 117 "ast_expr.y"
01133 { yyval.val = op_le (yyvsp[-2].val, yyvsp[0].val); ;}
01134 break;
01135
01136 case 12:
01137 #line 118 "ast_expr.y"
01138 { yyval.val = op_ne (yyvsp[-2].val, yyvsp[0].val); ;}
01139 break;
01140
01141 case 13:
01142 #line 119 "ast_expr.y"
01143 { yyval.val = op_plus (yyvsp[-2].val, yyvsp[0].val); ;}
01144 break;
01145
01146 case 14:
01147 #line 120 "ast_expr.y"
01148 { yyval.val = op_minus (yyvsp[-2].val, yyvsp[0].val); ;}
01149 break;
01150
01151 case 15:
01152 #line 121 "ast_expr.y"
01153 { yyval.val = op_times (yyvsp[-2].val, yyvsp[0].val); ;}
01154 break;
01155
01156 case 16:
01157 #line 122 "ast_expr.y"
01158 { yyval.val = op_div (yyvsp[-2].val, yyvsp[0].val); ;}
01159 break;
01160
01161 case 17:
01162 #line 123 "ast_expr.y"
01163 { yyval.val = op_rem (yyvsp[-2].val, yyvsp[0].val); ;}
01164 break;
01165
01166 case 18:
01167 #line 124 "ast_expr.y"
01168 { yyval.val = op_colon (yyvsp[-2].val, yyvsp[0].val); ;}
01169 break;
01170
01171
01172 }
01173
01174
01175 #line 1176 "ast_expr.c"
01176
01177 yyvsp -= yylen;
01178 yyssp -= yylen;
01179
01180
01181 YY_STACK_PRINT (yyss, yyssp);
01182
01183 *++yyvsp = yyval;
01184
01185
01186
01187
01188
01189
01190 yyn = yyr1[yyn];
01191
01192 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
01193 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
01194 yystate = yytable[yystate];
01195 else
01196 yystate = yydefgoto[yyn - YYNTOKENS];
01197
01198 goto yynewstate;
01199
01200
01201
01202
01203
01204 yyerrlab:
01205
01206 if (!yyerrstatus)
01207 {
01208 ++yynerrs;
01209 #if YYERROR_VERBOSE
01210 yyn = yypact[yystate];
01211
01212 if (YYPACT_NINF < yyn && yyn < YYLAST)
01213 {
01214 YYSIZE_T yysize = 0;
01215 int yytype = YYTRANSLATE (yychar);
01216 char *yymsg;
01217 int yyx, yycount;
01218
01219 yycount = 0;
01220
01221
01222 for (yyx = yyn < 0 ? -yyn : 0;
01223 yyx < (int) (sizeof (yytname) / sizeof (char *)); yyx++)
01224 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
01225 yysize += yystrlen (yytname[yyx]) + 15, yycount++;
01226 yysize += yystrlen ("syntax error, unexpected ") + 1;
01227 yysize += yystrlen (yytname[yytype]);
01228 yymsg = (char *) YYSTACK_ALLOC (yysize);
01229 if (yymsg != 0)
01230 {
01231 char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
01232 yyp = yystpcpy (yyp, yytname[yytype]);
01233
01234 if (yycount < 5)
01235 {
01236 yycount = 0;
01237 for (yyx = yyn < 0 ? -yyn : 0;
01238 yyx < (int) (sizeof (yytname) / sizeof (char *));
01239 yyx++)
01240 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
01241 {
01242 const char *yyq = ! yycount ? ", expecting " : " or ";
01243 yyp = yystpcpy (yyp, yyq);
01244 yyp = yystpcpy (yyp, yytname[yyx]);
01245 yycount++;
01246 }
01247 }
01248 yyerror (yymsg);
01249 YYSTACK_FREE (yymsg);
01250 }
01251 else
01252 yyerror ("syntax error; also virtual memory exhausted");
01253 }
01254 else
01255 #endif
01256 yyerror ("syntax error");
01257 }
01258
01259
01260
01261 if (yyerrstatus == 3)
01262 {
01263
01264
01265
01266
01267 if (yychar == YYEOF)
01268 {
01269
01270 YYPOPSTACK;
01271
01272 while (yyss < yyssp)
01273 {
01274 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
01275 yydestruct (yystos[*yyssp], yyvsp);
01276 YYPOPSTACK;
01277 }
01278 YYABORT;
01279 }
01280
01281 YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
01282 yydestruct (yytoken, &yylval);
01283 yychar = YYEMPTY;
01284
01285 }
01286
01287
01288
01289 goto yyerrlab1;
01290
01291
01292
01293
01294
01295 yyerrlab1:
01296 yyerrstatus = 3;
01297
01298 for (;;)
01299 {
01300 yyn = yypact[yystate];
01301 if (yyn != YYPACT_NINF)
01302 {
01303 yyn += YYTERROR;
01304 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
01305 {
01306 yyn = yytable[yyn];
01307 if (0 < yyn)
01308 break;
01309 }
01310 }
01311
01312
01313 if (yyssp == yyss)
01314 YYABORT;
01315
01316 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
01317 yydestruct (yystos[yystate], yyvsp);
01318 yyvsp--;
01319 yystate = *--yyssp;
01320
01321 YY_STACK_PRINT (yyss, yyssp);
01322 }
01323
01324 if (yyn == YYFINAL)
01325 YYACCEPT;
01326
01327 YYDPRINTF ((stderr, "Shifting error token, "));
01328
01329 *++yyvsp = yylval;
01330
01331
01332 yystate = yyn;
01333 goto yynewstate;
01334
01335
01336
01337
01338
01339 yyacceptlab:
01340 yyresult = 0;
01341 goto yyreturn;
01342
01343
01344
01345
01346 yyabortlab:
01347 yyresult = 1;
01348 goto yyreturn;
01349
01350 #ifndef yyoverflow
01351
01352
01353
01354 yyoverflowlab:
01355 yyerror ("parser stack overflow");
01356 yyresult = 2;
01357
01358 #endif
01359
01360 yyreturn:
01361 #ifndef yyoverflow
01362 if (yyss != yyssa)
01363 YYSTACK_FREE (yyss);
01364 #endif
01365 return yyresult;
01366 }
01367
01368
01369 #line 128 "ast_expr.y"
01370
01371
01372 static struct val *
01373 make_integer (i)
01374 quad_t i;
01375 {
01376 struct val *vp;
01377
01378 vp = (struct val *) malloc (sizeof (*vp));
01379 if (vp == NULL) {
01380 ast_log(LOG_WARNING, "malloc() failed\n");
01381 return(NULL);
01382 }
01383
01384 vp->type = integer;
01385 vp->u.i = i;
01386 return vp;
01387 }
01388
01389 static struct val *
01390 make_str (s)
01391 const char *s;
01392 {
01393 struct val *vp;
01394 size_t i;
01395 int isint;
01396
01397 vp = (struct val *) malloc (sizeof (*vp));
01398 if (vp == NULL || ((vp->u.s = strdup (s)) == NULL)) {
01399 ast_log(LOG_WARNING,"malloc() failed\n");
01400 return(NULL);
01401 }
01402
01403 for(i = 1, isint = isdigit(s[0]) || s[0] == '-';
01404 isint && i < strlen(s);
01405 i++)
01406 {
01407 if(!isdigit(s[i]))
01408 isint = 0;
01409 }
01410
01411 if (isint)
01412 vp->type = numeric_string;
01413 else
01414 vp->type = string;
01415
01416 return vp;
01417 }
01418
01419
01420 static void
01421 free_value (vp)
01422 struct val *vp;
01423 {
01424 if (vp==NULL) {
01425 return;
01426 }
01427 if (vp->type == string || vp->type == numeric_string)
01428 free (vp->u.s);
01429 }
01430
01431
01432 static quad_t
01433 to_integer (vp)
01434 struct val *vp;
01435 {
01436 quad_t i;
01437
01438 if (vp == NULL) {
01439 ast_log(LOG_WARNING,"vp==NULL in to_integer()\n");
01440 return(0);
01441 }
01442
01443 if (vp->type == integer)
01444 return 1;
01445
01446 if (vp->type == string)
01447 return 0;
01448
01449
01450 errno = 0;
01451 i = strtoq(vp->u.s, (char**)NULL, 10);
01452 if (errno != 0) {
01453 free(vp->u.s);
01454 ast_log(LOG_WARNING,"overflow\n");
01455 return(0);
01456 }
01457 free (vp->u.s);
01458 vp->u.i = i;
01459 vp->type = integer;
01460 return 1;
01461 }
01462
01463 static void
01464 to_string (vp)
01465 struct val *vp;
01466 {
01467 char *tmp;
01468
01469 if (vp->type == string || vp->type == numeric_string)
01470 return;
01471
01472 tmp = malloc ((size_t)25);
01473 if (tmp == NULL) {
01474 ast_log(LOG_WARNING,"malloc() failed\n");
01475 return;
01476 }
01477
01478 sprintf (tmp, "%lld", (long long)vp->u.i);
01479 vp->type = string;
01480 vp->u.s = tmp;
01481 }
01482
01483
01484 static int
01485 isstring (vp)
01486 struct val *vp;
01487 {
01488
01489 return (vp->type == string);
01490 }
01491
01492
01493 static int
01494 ast_yylex (YYSTYPE *lvalp, struct parser_control *karoto)
01495 {
01496 char *p;
01497
01498 if (karoto->firsttoken==1) {
01499 p=strtok_r(karoto->argv," ",&(karoto->ptrptr));
01500 karoto->firsttoken=0;
01501 } else {
01502 p=strtok_r(NULL," ",&(karoto->ptrptr));
01503 }
01504
01505 if (p==NULL) {
01506 return (0);
01507 }
01508
01509
01510 if (strlen (p) == 1) {
01511 if (strchr ("|&=<>+-*/%:()", *p))
01512 return (*p);
01513 } else if (strlen (p) == 2 && p[1] == '=') {
01514 switch (*p) {
01515 case '>': return (GE);
01516 case '<': return (LE);
01517 case '!': return (NE);
01518 }
01519 }
01520
01521 lvalp->val = make_str (p);
01522 return (TOKEN);
01523 }
01524
01525 static int
01526 is_zero_or_null (vp)
01527 struct val *vp;
01528 {
01529 if (vp->type == integer) {
01530 return (vp->u.i == 0);
01531 } else {
01532 return (*vp->u.s == 0 || (to_integer (vp) && vp->u.i == 0));
01533 }
01534
01535 }
01536
01537 char *ast_expr (char *arg)
01538 {
01539 struct parser_control karoto;
01540
01541 char *kota;
01542 char *pirouni;
01543
01544 kota=strdup(arg);
01545 karoto.result = NULL;
01546 karoto.firsttoken=1;
01547 karoto.argv=kota;
01548
01549 ast_yyparse ((void *)&karoto);
01550
01551 free(kota);
01552
01553 if (karoto.result==NULL) {
01554 pirouni=strdup("0");
01555 return(pirouni);
01556 } else {
01557 if (karoto.result->type == integer) {
01558 pirouni=malloc(256);
01559 sprintf (pirouni,"%lld", (long long)karoto.result->u.i);
01560 }
01561 else {
01562 pirouni=strdup(karoto.result->u.s);
01563 }
01564 free(karoto.result);
01565 }
01566 return(pirouni);
01567 }
01568
01569 #ifdef STANDALONE
01570
01571 int main(int argc,char **argv) {
01572 char *s;
01573
01574 s=ast_expr(argv[1]);
01575
01576 printf("=====%s======\n",s);
01577 }
01578
01579 #endif
01580
01581 static int
01582 ast_yyerror (s)
01583 const char *s;
01584 {
01585 ast_log(LOG_WARNING,"ast_yyerror(): syntax error: %s\n",s);
01586 return(0);
01587 }
01588
01589
01590 static struct val *
01591 op_or (a, b)
01592 struct val *a, *b;
01593 {
01594 if (is_zero_or_null (a)) {
01595 free_value (a);
01596 return (b);
01597 } else {
01598 free_value (b);
01599 return (a);
01600 }
01601 }
01602
01603 static struct val *
01604 op_and (a, b)
01605 struct val *a, *b;
01606 {
01607 if (is_zero_or_null (a) || is_zero_or_null (b)) {
01608 free_value (a);
01609 free_value (b);
01610 return (make_integer ((quad_t)0));
01611 } else {
01612 free_value (b);
01613 return (a);
01614 }
01615 }
01616
01617 static struct val *
01618 op_eq (a, b)
01619 struct val *a, *b;
01620 {
01621 struct val *r;
01622
01623 if (isstring (a) || isstring (b)) {
01624 to_string (a);
01625 to_string (b);
01626 r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) == 0));
01627 } else {
01628 (void)to_integer(a);
01629 (void)to_integer(b);
01630 r = make_integer ((quad_t)(a->u.i == b->u.i));
01631 }
01632
01633 free_value (a);
01634 free_value (b);
01635 return r;
01636 }
01637
01638 static struct val *
01639 op_gt (a, b)
01640 struct val *a, *b;
01641 {
01642 struct val *r;
01643
01644 if (isstring (a) || isstring (b)) {
01645 to_string (a);
01646 to_string (b);
01647 r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) > 0));
01648 } else {
01649 (void)to_integer(a);
01650 (void)to_integer(b);
01651 r = make_integer ((quad_t)(a->u.i > b->u.i));
01652 }
01653
01654 free_value (a);
01655 free_value (b);
01656 return r;
01657 }
01658
01659 static struct val *
01660 op_lt (a, b)
01661 struct val *a, *b;
01662 {
01663 struct val *r;
01664
01665 if (isstring (a) || isstring (b)) {
01666 to_string (a);
01667 to_string (b);
01668 r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) < 0));
01669 } else {
01670 (void)to_integer(a);
01671 (void)to_integer(b);
01672 r = make_integer ((quad_t)(a->u.i < b->u.i));
01673 }
01674
01675 free_value (a);
01676 free_value (b);
01677 return r;
01678 }
01679
01680 static struct val *
01681 op_ge (a, b)
01682 struct val *a, *b;
01683 {
01684 struct val *r;
01685
01686 if (isstring (a) || isstring (b)) {
01687 to_string (a);
01688 to_string (b);
01689 r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) >= 0));
01690 } else {
01691 (void)to_integer(a);
01692 (void)to_integer(b);
01693 r = make_integer ((quad_t)(a->u.i >= b->u.i));
01694 }
01695
01696 free_value (a);
01697 free_value (b);
01698 return r;
01699 }
01700
01701 static struct val *
01702 op_le (a, b)
01703 struct val *a, *b;
01704 {
01705 struct val *r;
01706
01707 if (isstring (a) || isstring (b)) {
01708 to_string (a);
01709 to_string (b);
01710 r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) <= 0));
01711 } else {
01712 (void)to_integer(a);
01713 (void)to_integer(b);
01714 r = make_integer ((quad_t)(a->u.i <= b->u.i));
01715 }
01716
01717 free_value (a);
01718 free_value (b);
01719 return r;
01720 }
01721
01722 static struct val *
01723 op_ne (a, b)
01724 struct val *a, *b;
01725 {
01726 struct val *r;
01727
01728 if (isstring (a) || isstring (b)) {
01729 to_string (a);
01730 to_string (b);
01731 r = make_integer ((quad_t)(strcoll (a->u.s, b->u.s) != 0));
01732 } else {
01733 (void)to_integer(a);
01734 (void)to_integer(b);
01735 r = make_integer ((quad_t)(a->u.i != b->u.i));
01736 }
01737
01738 free_value (a);
01739 free_value (b);
01740 return r;
01741 }
01742
01743 static int
01744 chk_plus (a, b, r)
01745 quad_t a, b, r;
01746 {
01747
01748 if (a > 0 && b > 0 && r <= 0)
01749 return 1;
01750
01751 if (a < 0 && b < 0 && r >= 0)
01752 return 1;
01753
01754 return 0;
01755 }
01756
01757 static struct val *
01758 op_plus (a, b)
01759 struct val *a, *b;
01760 {
01761 struct val *r;
01762
01763 if (!to_integer (a) || !to_integer (b)) {
01764 ast_log(LOG_WARNING,"non-numeric argument\n");
01765 free_value(a);
01766 free_value(b);
01767 return(NULL);
01768 }
01769
01770 r = make_integer ((a->u.i + b->u.i));
01771 if (chk_plus (a->u.i, b->u.i, r->u.i)) {
01772 ast_log(LOG_WARNING,"overflow\n");
01773 free_value(a);
01774 free_value(b);
01775 return(NULL);
01776 }
01777 free_value (a);
01778 free_value (b);
01779 return r;
01780 }
01781
01782 static int
01783 chk_minus (a, b, r)
01784 quad_t a, b, r;
01785 {
01786
01787 if (b == QUAD_MIN) {
01788 if (a >= 0)
01789 return 1;
01790 else
01791 return 0;
01792 }
01793
01794 return chk_plus (a, -b, r);
01795 }
01796
01797 static struct val *
01798 op_minus (a, b)
01799 struct val *a, *b;
01800 {
01801 struct val *r;
01802
01803 if (!to_integer (a) || !to_integer (b)) {
01804 free_value(a);
01805 free_value(b);
01806 ast_log(LOG_WARNING, "non-numeric argument\n");
01807 return(NULL);
01808 }
01809
01810 r = make_integer ((a->u.i - b->u.i));
01811 if (chk_minus (a->u.i, b->u.i, r->u.i)) {
01812 free_value(a);
01813 free_value(b);
01814 ast_log(LOG_WARNING, "overload\n");
01815 return(NULL);
01816 }
01817 free_value (a);
01818 free_value (b);
01819 return r;
01820 }
01821
01822 static int
01823 chk_times (a, b, r)
01824 quad_t a, b, r;
01825 {
01826
01827 if (a == 0)
01828 return 0;
01829
01830 if (r / a != b)
01831 return 1;
01832 return 0;
01833 }
01834
01835 static struct val *
01836 op_times (a, b)
01837 struct val *a, *b;
01838 {
01839 struct val *r;
01840
01841 if (!to_integer (a) || !to_integer (b)) {
01842 free_value(a);
01843 free_value(b);
01844 ast_log(LOG_WARNING, "non-numeric argument\n");
01845 return(NULL);
01846 }
01847
01848 r = make_integer ((a->u.i * b->u.i));
01849 if (chk_times (a->u.i, b->u.i, r->u.i)) {
01850 ast_log(LOG_WARNING, "overflow\n");
01851 free_value(a);
01852 free_value(b);
01853 return(NULL);
01854 }
01855 free_value (a);
01856 free_value (b);
01857 return (r);
01858 }
01859
01860 static int
01861 chk_div (a, b)
01862 quad_t a, b;
01863 {
01864
01865
01866 if (a == QUAD_MIN && b == -1)
01867 return 1;
01868
01869 return 0;
01870 }
01871
01872 static struct val *
01873 op_div (a, b)
01874 struct val *a, *b;
01875 {
01876 struct val *r;
01877
01878 if (!to_integer (a) || !to_integer (b)) {
01879 free_value(a);
01880 free_value(b);
01881 ast_log(LOG_WARNING, "non-numeric argument\n");
01882 return(NULL);
01883 }
01884
01885 if (b->u.i == 0) {
01886 ast_log(LOG_WARNING, "division by zero\n");
01887 free_value(a);
01888 free_value(b);
01889 return(NULL);
01890 }
01891
01892 r = make_integer ((a->u.i / b->u.i));
01893 if (chk_div (a->u.i, b->u.i)) {
01894 ast_log(LOG_WARNING, "overflow\n");
01895 free_value(a);
01896 free_value(b);
01897 return(NULL);
01898 }
01899 free_value (a);
01900 free_value (b);
01901 return r;
01902 }
01903
01904 static struct val *
01905 op_rem (a, b)
01906 struct val *a, *b;
01907 {
01908 struct val *r;
01909
01910 if (!to_integer (a) || !to_integer (b)) {
01911 ast_log(LOG_WARNING, "non-numeric argument\n");
01912 free_value(a);
01913 free_value(b);
01914 return(NULL);
01915 }
01916
01917 if (b->u.i == 0) {
01918 ast_log(LOG_WARNING, "div by zero\n");
01919 free_value(a);
01920 free_value(b);
01921 return(NULL);
01922 }
01923
01924 r = make_integer ((a->u.i % b->u.i));
01925
01926 free_value (a);
01927 free_value (b);
01928 return r;
01929 }
01930
01931 static struct val *
01932 op_colon (a, b)
01933 struct val *a, *b;
01934 {
01935 regex_t rp;
01936 regmatch_t rm[2];
01937 char errbuf[256];
01938 int eval;
01939 struct val *v;
01940
01941
01942 to_string(a);
01943 to_string(b);
01944
01945
01946 if ((eval = regcomp (&rp, b->u.s, 0)) != 0) {
01947 regerror (eval, &rp, errbuf, sizeof(errbuf));
01948 ast_log(LOG_WARNING,"regcomp() error : %s",errbuf);
01949 free_value(a);
01950 free_value(b);
01951 return(NULL);
01952 }
01953
01954
01955
01956 if (regexec(&rp, a->u.s, (size_t)2, rm, 0) == 0 && rm[0].rm_so == 0) {
01957 if (rm[1].rm_so >= 0) {
01958 *(a->u.s + rm[1].rm_eo) = '\0';
01959 v = make_str (a->u.s + rm[1].rm_so);
01960
01961 } else {
01962 v = make_integer ((quad_t)(rm[0].rm_eo - rm[0].rm_so));
01963 }
01964 } else {
01965 if (rp.re_nsub == 0) {
01966 v = make_integer ((quad_t)0);
01967 } else {
01968 v = make_str ("");
01969 }
01970 }
01971
01972
01973 free_value (a);
01974 free_value (b);
01975 regfree (&rp);
01976
01977 return v;
01978 }
01979
01980