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