From 1d990be4aec3ba8966b46afd092d4a359508f570 Mon Sep 17 00:00:00 2001 From: Frank Lahm Date: Thu, 1 Nov 2012 18:57:04 +0100 Subject: [PATCH] Support unix dates and comparison with dates for attributes --- etc/afpd/spotlight_rawquery_lexer.c | 223 +++++++++------------- etc/afpd/spotlight_rawquery_lexer.l | 7 +- etc/afpd/spotlight_rawquery_parser.c | 273 ++++++++++++++++----------- etc/afpd/spotlight_rawquery_parser.h | 66 +++---- etc/afpd/spotlight_rawquery_parser.y | 64 +++++-- 5 files changed, 335 insertions(+), 298 deletions(-) diff --git a/etc/afpd/spotlight_rawquery_lexer.c b/etc/afpd/spotlight_rawquery_lexer.c index 05f1bdc2..d2264ed3 100644 --- a/etc/afpd/spotlight_rawquery_lexer.c +++ b/etc/afpd/spotlight_rawquery_lexer.c @@ -359,8 +359,8 @@ static void yy_fatal_error (yyconst char msg[] ); *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 20 -#define YY_END_OF_BUFFER 21 +#define YY_NUM_RULES 19 +#define YY_END_OF_BUFFER 20 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -368,34 +368,32 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[75] = +static yyconst flex_int16_t yy_accept[52] = { 0, - 0, 0, 21, 20, 19, 19, 20, 9, 20, 20, - 10, 11, 8, 18, 16, 20, 17, 8, 8, 8, - 8, 20, 0, 15, 0, 12, 8, 14, 8, 5, - 8, 8, 8, 13, 0, 0, 8, 8, 4, 8, - 8, 0, 0, 8, 8, 8, 7, 0, 0, 8, - 8, 6, 0, 0, 8, 0, 0, 1, 0, 0, - 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 3, 0 + 0, 0, 20, 19, 18, 19, 8, 19, 19, 9, + 10, 7, 17, 15, 19, 16, 7, 7, 7, 7, + 19, 14, 0, 11, 7, 13, 7, 4, 7, 7, + 7, 12, 0, 7, 3, 7, 7, 0, 7, 7, + 6, 0, 7, 5, 0, 7, 0, 1, 0, 2, + 0 } ; static yyconst flex_int32_t yy_ec[256] = { 0, - 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 4, 5, 1, 6, 1, 7, 1, 8, - 9, 10, 1, 11, 12, 13, 1, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 14, 1, 15, - 16, 17, 1, 1, 10, 10, 10, 10, 10, 10, - 10, 10, 18, 10, 10, 10, 10, 10, 10, 10, - 10, 19, 10, 20, 10, 10, 10, 10, 10, 21, - 1, 1, 1, 1, 1, 1, 22, 10, 23, 24, - - 25, 26, 27, 10, 28, 10, 10, 29, 30, 31, - 32, 10, 10, 33, 34, 35, 36, 10, 37, 10, - 10, 10, 1, 38, 1, 1, 1, 1, 1, 1, + 1, 2, 3, 4, 1, 5, 1, 6, 1, 7, + 8, 9, 1, 10, 9, 11, 1, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 9, 9, 1, 12, + 13, 14, 1, 1, 9, 9, 9, 9, 9, 9, + 9, 9, 15, 9, 9, 9, 9, 9, 9, 9, + 9, 16, 9, 9, 9, 9, 9, 9, 9, 9, + 1, 1, 1, 1, 1, 1, 17, 9, 18, 19, + + 20, 21, 22, 9, 23, 9, 9, 24, 25, 26, + 27, 9, 9, 28, 29, 30, 31, 9, 32, 9, + 9, 9, 1, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -412,104 +410,62 @@ static yyconst flex_int32_t yy_ec[256] = 1, 1, 1, 1, 1 } ; -static yyconst flex_int32_t yy_meta[39] = +static yyconst flex_int32_t yy_meta[34] = { 0, - 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, - 1, 3, 1, 1, 1, 1, 1, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 1 + 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 1 } ; -static yyconst flex_int16_t yy_base[89] = +static yyconst flex_int16_t yy_base[53] = { 0, - 0, 0, 212, 0, 0, 226, 193, 0, 171, 196, - 0, 0, 38, 0, 0, 184, 0, 166, 53, 172, - 158, 150, 0, 0, 157, 0, 90, 0, 163, 0, - 156, 150, 142, 0, 0, 147, 128, 154, 0, 141, - 149, 161, 68, 160, 155, 156, 159, 0, 118, 77, - 157, 76, 0, 59, 158, 74, 51, 72, 0, 51, - 0, 226, 62, 0, 0, 67, 0, 0, 65, 0, - 0, 57, 226, 226, 186, 189, 192, 38, 195, 198, - 201, 204, 207, 210, 213, 216, 219, 222 + 0, 0, 63, 64, 64, 49, 64, 31, 54, 64, + 64, 0, 64, 64, 46, 64, 32, 15, 40, 28, + 22, 64, 31, 64, 0, 64, 37, 0, 33, 27, + 19, 64, 24, 31, 0, 17, 25, 24, 17, 22, + 0, 30, 18, 0, 16, 18, 8, 0, 9, 64, + 64, 33 } ; -static yyconst flex_int16_t yy_def[89] = +static yyconst flex_int16_t yy_def[53] = { 0, - 74, 1, 74, 75, 75, 74, 75, 75, 75, 75, - 75, 75, 74, 75, 75, 75, 75, 13, 13, 13, - 13, 75, 76, 76, 76, 76, 74, 76, 27, 27, - 27, 27, 27, 76, 77, 77, 74, 37, 37, 37, - 37, 74, 74, 78, 78, 78, 78, 79, 74, 78, - 78, 78, 80, 74, 78, 74, 74, 78, 81, 74, - 82, 74, 74, 83, 84, 74, 85, 86, 74, 87, - 88, 74, 74, 0, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74 + 51, 1, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 52, 51, 51, 51, 51, 52, 52, 52, 52, + 51, 51, 51, 51, 52, 51, 52, 52, 52, 52, + 52, 51, 51, 52, 52, 52, 52, 51, 52, 52, + 52, 51, 52, 52, 51, 52, 51, 52, 51, 51, + 0, 51 } ; -static yyconst flex_int16_t yy_nxt[265] = +static yyconst flex_int16_t yy_nxt[98] = { 0, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 4, 4, 4, 15, 16, 17, 18, 13, 13, - 13, 13, 19, 13, 13, 20, 13, 13, 13, 13, - 13, 13, 13, 13, 21, 13, 13, 22, 23, 23, - 50, 23, 23, 23, 23, 23, 23, 27, 23, 23, - 23, 23, 23, 23, 23, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 23, 30, 73, 70, 48, - 67, 64, 62, 74, 60, 59, 57, 74, 74, 31, - 35, 35, 49, 35, 35, 35, 35, 35, 35, 37, - - 35, 35, 35, 35, 35, 35, 35, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 35, 42, 42, - 54, 42, 42, 42, 42, 42, 42, 44, 42, 42, - 42, 42, 42, 42, 42, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 44, 44, 44, 44, 44, - 44, 44, 44, 44, 44, 42, 48, 48, 74, 74, - 48, 48, 48, 47, 46, 45, 43, 41, 40, 39, - 52, 38, 58, 55, 36, 51, 23, 34, 23, 35, - 33, 35, 42, 32, 42, 53, 29, 53, 56, 28, - - 56, 61, 26, 61, 63, 25, 63, 65, 24, 65, - 66, 74, 66, 68, 74, 68, 69, 74, 69, 71, - 74, 71, 72, 74, 72, 3, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74 + 4, 14, 15, 16, 17, 12, 12, 18, 12, 12, + 19, 12, 12, 12, 12, 12, 12, 12, 12, 20, + 12, 12, 21, 28, 25, 50, 49, 48, 47, 46, + 45, 44, 43, 42, 41, 40, 29, 39, 38, 37, + 36, 35, 34, 33, 32, 31, 30, 27, 26, 24, + 23, 22, 51, 3, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51 + } ; -static yyconst flex_int16_t yy_chk[265] = +static yyconst flex_int16_t yy_chk[98] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 13, 13, - 78, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 19, 72, 69, 43, - 66, 63, 60, 58, 57, 56, 54, 52, 50, 19, - 27, 27, 43, 27, 27, 27, 27, 27, 27, 27, - - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 27, 27, 27, 27, 27, 27, 27, 27, 37, 37, - 49, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 37, 37, 37, 37, - 37, 37, 37, 37, 37, 37, 45, 46, 51, 55, - 47, 44, 42, 41, 40, 38, 36, 33, 32, 31, - 46, 29, 55, 51, 25, 45, 75, 22, 75, 76, - 21, 76, 77, 20, 77, 79, 18, 79, 80, 16, - - 80, 81, 10, 81, 82, 9, 82, 83, 7, 83, - 84, 3, 84, 85, 0, 85, 86, 0, 86, 87, - 0, 87, 88, 0, 88, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74, 74, 74, 74, 74, 74, 74, - 74, 74, 74, 74 + 1, 1, 1, 18, 52, 49, 47, 46, 45, 43, + 42, 40, 39, 38, 37, 36, 18, 34, 33, 31, + 30, 29, 27, 23, 21, 20, 19, 17, 15, 9, + 8, 6, 3, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 51 + } ; static yy_state_type yy_last_accepting_state; @@ -534,7 +490,7 @@ char *yytext; #include #include "spotlight.h" #include "spotlight_rawquery_parser.h" -#line 538 "spotlight_rawquery_lexer.c" +#line 494 "spotlight_rawquery_lexer.c" #define INITIAL 0 @@ -718,7 +674,7 @@ YY_DECL #line 10 "spotlight_rawquery_lexer.l" -#line 722 "spotlight_rawquery_lexer.c" +#line 678 "spotlight_rawquery_lexer.c" if ( !(yy_init) ) { @@ -771,13 +727,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 75 ) + if ( yy_current_state >= 52 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 226 ); + while ( yy_base[yy_current_state] != 64 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -809,100 +765,95 @@ return FUNC_INRANGE; case 2: YY_RULE_SETUP #line 12 "spotlight_rawquery_lexer.l" -return DATE_SPEC; +return DATE_ISO; YY_BREAK case 3: YY_RULE_SETUP #line 13 "spotlight_rawquery_lexer.l" -{yylval.sval = talloc_strdup(ssp_slq, yytext); return DATE;} +/* ignore case specifier */ YY_BREAK case 4: YY_RULE_SETUP #line 14 "spotlight_rawquery_lexer.l" -/* ignore case specifier */ +/* ignore */ YY_BREAK case 5: YY_RULE_SETUP #line 15 "spotlight_rawquery_lexer.l" -/* ignore */ +{yylval.bval = false; return BOOL;} YY_BREAK case 6: YY_RULE_SETUP #line 16 "spotlight_rawquery_lexer.l" -{yylval.bval = false; return BOOL;} +{yylval.bval = true; return BOOL;} YY_BREAK case 7: YY_RULE_SETUP #line 17 "spotlight_rawquery_lexer.l" -{yylval.bval = true; return BOOL;} +{yylval.sval = talloc_strdup(ssp_slq, yytext); return WORD;} YY_BREAK case 8: YY_RULE_SETUP #line 18 "spotlight_rawquery_lexer.l" -{yylval.sval = talloc_strdup(ssp_slq, yytext); return WORD;} +return QUOTE; YY_BREAK case 9: YY_RULE_SETUP #line 19 "spotlight_rawquery_lexer.l" -return QUOTE; +return OBRACE; YY_BREAK case 10: YY_RULE_SETUP #line 20 "spotlight_rawquery_lexer.l" -return OBRACE; +return CBRACE; YY_BREAK case 11: YY_RULE_SETUP #line 21 "spotlight_rawquery_lexer.l" -return CBRACE; +return AND; YY_BREAK case 12: YY_RULE_SETUP #line 22 "spotlight_rawquery_lexer.l" -return AND; +return OR; YY_BREAK case 13: YY_RULE_SETUP #line 23 "spotlight_rawquery_lexer.l" -return OR; +return EQUAL; YY_BREAK case 14: YY_RULE_SETUP #line 24 "spotlight_rawquery_lexer.l" -return EQUAL; +return UNEQUAL; YY_BREAK case 15: YY_RULE_SETUP #line 25 "spotlight_rawquery_lexer.l" -return UNEQUAL; +return LT; YY_BREAK case 16: YY_RULE_SETUP #line 26 "spotlight_rawquery_lexer.l" -return LT; +return GT; YY_BREAK case 17: YY_RULE_SETUP #line 27 "spotlight_rawquery_lexer.l" -return GT; +return COMMA; YY_BREAK case 18: +/* rule 18 can match eol */ YY_RULE_SETUP #line 28 "spotlight_rawquery_lexer.l" -return COMMA; +/* ignore */ YY_BREAK case 19: -/* rule 19 can match eol */ YY_RULE_SETUP #line 29 "spotlight_rawquery_lexer.l" -/* ignore */ - YY_BREAK -case 20: -YY_RULE_SETUP -#line 30 "spotlight_rawquery_lexer.l" ECHO; YY_BREAK -#line 906 "spotlight_rawquery_lexer.c" +#line 857 "spotlight_rawquery_lexer.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -1194,7 +1145,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 75 ) + if ( yy_current_state >= 52 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -1222,11 +1173,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 75 ) + if ( yy_current_state >= 52 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 74); + yy_is_jam = (yy_current_state == 51); return yy_is_jam ? 0 : yy_current_state; } @@ -1900,7 +1851,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 30 "spotlight_rawquery_lexer.l" +#line 29 "spotlight_rawquery_lexer.l" diff --git a/etc/afpd/spotlight_rawquery_lexer.l b/etc/afpd/spotlight_rawquery_lexer.l index b3b4bce2..6ee3de52 100644 --- a/etc/afpd/spotlight_rawquery_lexer.l +++ b/etc/afpd/spotlight_rawquery_lexer.l @@ -9,20 +9,19 @@ %% InRange return FUNC_INRANGE; -\$time\.iso return DATE_SPEC; -....-..-..T..:..:..Z {yylval.sval = talloc_strdup(ssp_slq, yytext); return DATE;} +\$time\.iso return DATE_ISO; cwd /* ignore case specifier */ cd /* ignore */ false {yylval.bval = false; return BOOL;} true {yylval.bval = true; return BOOL;} -[a-zA-Z0-9\*]+ {yylval.sval = talloc_strdup(ssp_slq, yytext); return WORD;} +[a-zA-Z0-9\*\:\-]+ {yylval.sval = talloc_strdup(ssp_slq, yytext); return WORD;} \" return QUOTE; \( return OBRACE; \) return CBRACE; \&\& return AND; \|\| return OR; \=\= return EQUAL; -!\= return UNEQUAL; +\!\= return UNEQUAL; \< return LT; \> return GT; \, return COMMA; diff --git a/etc/afpd/spotlight_rawquery_parser.c b/etc/afpd/spotlight_rawquery_parser.c index b4453de8..ac9a521a 100644 --- a/etc/afpd/spotlight_rawquery_parser.c +++ b/etc/afpd/spotlight_rawquery_parser.c @@ -68,13 +68,19 @@ /* Line 268 of yacc.c */ #line 1 "spotlight_rawquery_parser.y" + #include + #include #include #include + #include + #include + #include #include #include + #include "spotlight_SPARQL_map.h" #include "spotlight.h" @@ -88,9 +94,10 @@ /* forward declarations */ static const char *map_expr(const char *attr, char op, const char *val); - static const char *map_daterange(const char *dateattr, const char *date1, const char *date2); - - /* global vars, eg needed by the lexer */ + static const char *map_daterange(const char *dateattr, time_t date1, time_t date2); + static time_t isodate2unix(const char *s); + + /* global vars, eg needed by the lexer */ slq_t *ssp_slq; /* local vars */ @@ -99,7 +106,7 @@ /* Line 268 of yacc.c */ -#line 103 "spotlight_rawquery_parser.c" +#line 110 "spotlight_rawquery_parser.c" /* Enabling traces. */ #ifndef YYDEBUG @@ -126,39 +133,37 @@ /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { - DATE = 258, - WORD = 259, - BOOL = 260, - FUNC_INRANGE = 261, - DATE_SPEC = 262, - OBRACE = 263, - CBRACE = 264, - EQUAL = 265, - UNEQUAL = 266, - GT = 267, - LT = 268, - COMMA = 269, - QUOTE = 270, - AND = 271, - OR = 272 + WORD = 258, + BOOL = 259, + FUNC_INRANGE = 260, + DATE_ISO = 261, + OBRACE = 262, + CBRACE = 263, + EQUAL = 264, + UNEQUAL = 265, + GT = 266, + LT = 267, + COMMA = 268, + QUOTE = 269, + AND = 270, + OR = 271 }; #endif /* Tokens. */ -#define DATE 258 -#define WORD 259 -#define BOOL 260 -#define FUNC_INRANGE 261 -#define DATE_SPEC 262 -#define OBRACE 263 -#define CBRACE 264 -#define EQUAL 265 -#define UNEQUAL 266 -#define GT 267 -#define LT 268 -#define COMMA 269 -#define QUOTE 270 -#define AND 271 -#define OR 272 +#define WORD 258 +#define BOOL 259 +#define FUNC_INRANGE 260 +#define DATE_ISO 261 +#define OBRACE 262 +#define CBRACE 263 +#define EQUAL 264 +#define UNEQUAL 265 +#define GT 266 +#define LT 267 +#define COMMA 268 +#define QUOTE 269 +#define AND 270 +#define OR 271 @@ -168,16 +173,17 @@ typedef union YYSTYPE { /* Line 293 of yacc.c */ -#line 37 "spotlight_rawquery_parser.y" +#line 45 "spotlight_rawquery_parser.y" int ival; const char *sval; bool bval; + time_t tval; /* Line 293 of yacc.c */ -#line 181 "spotlight_rawquery_parser.c" +#line 187 "spotlight_rawquery_parser.c" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -187,21 +193,22 @@ typedef union YYSTYPE /* "%code provides" blocks. */ /* Line 340 of yacc.c */ -#line 32 "spotlight_rawquery_parser.y" +#line 39 "spotlight_rawquery_parser.y" + #define SPRAW_TIME_OFFSET 978307200 extern int map_spotlight_to_sparql_query(slq_t *slq, gchar **sparql_result); extern slq_t *ssp_slq; /* Line 340 of yacc.c */ -#line 199 "spotlight_rawquery_parser.c" +#line 206 "spotlight_rawquery_parser.c" /* Copy the second part of user declarations. */ /* Line 343 of yacc.c */ -#line 205 "spotlight_rawquery_parser.c" +#line 212 "spotlight_rawquery_parser.c" #ifdef short # undef short @@ -420,20 +427,20 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 2 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 51 +#define YYLAST 56 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 18 +#define YYNTOKENS 17 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 6 +#define YYNNTS 7 /* YYNRULES -- Number of rules. */ -#define YYNRULES 16 +#define YYNRULES 18 /* YYNRULES -- Number of states. */ -#define YYNSTATES 48 +#define YYNSTATES 47 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 272 +#define YYMAXUTOK 271 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -468,7 +475,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17 + 15, 16 }; #if YYDEBUG @@ -477,26 +484,27 @@ static const yytype_uint8 yytranslate[] = static const yytype_uint8 yyprhs[] = { 0, 0, 3, 4, 7, 9, 11, 15, 17, 19, - 23, 27, 31, 37, 43, 49, 55 + 23, 27, 31, 37, 43, 49, 55, 64, 69 }; /* YYRHS -- A `-1'-separated list of the rules' RHS. */ static const yytype_int8 yyrhs[] = { - 19, 0, -1, -1, 19, 20, -1, 21, -1, 5, - -1, 22, 17, 22, -1, 22, -1, 23, -1, 8, - 21, 9, -1, 21, 16, 21, -1, 21, 17, 21, - -1, 4, 10, 15, 4, 15, -1, 4, 11, 15, - 4, 15, -1, 4, 13, 15, 4, 15, -1, 4, - 12, 15, 4, 15, -1, 6, 8, 4, 14, 7, - 8, 3, 9, 14, 7, 8, 3, 9, 9, -1 + 18, 0, -1, -1, 18, 19, -1, 20, -1, 4, + -1, 21, 16, 21, -1, 21, -1, 22, -1, 7, + 20, 8, -1, 20, 15, 20, -1, 20, 16, 20, + -1, 3, 9, 14, 3, 14, -1, 3, 10, 14, + 3, 14, -1, 3, 12, 14, 3, 14, -1, 3, + 11, 14, 3, 14, -1, 5, 7, 3, 13, 23, + 13, 23, 8, -1, 6, 7, 3, 8, -1, 3, + -1 }; /* YYRLINE[YYN] -- source line where rule number YYN was defined. */ static const yytype_uint8 yyrline[] = { - 0, 57, 57, 59, 63, 73, 79, 85, 86, 87, - 88, 89, 98, 99, 100, 101, 105 + 0, 67, 67, 69, 73, 83, 89, 95, 96, 97, + 98, 99, 108, 109, 110, 111, 115, 119, 120 }; #endif @@ -505,10 +513,10 @@ static const yytype_uint8 yyrline[] = First, the terminals, then, starting at YYNTOKENS, nonterminals. */ static const char *const yytname[] = { - "$end", "error", "$undefined", "DATE", "WORD", "BOOL", "FUNC_INRANGE", - "DATE_SPEC", "OBRACE", "CBRACE", "EQUAL", "UNEQUAL", "GT", "LT", "COMMA", + "$end", "error", "$undefined", "WORD", "BOOL", "FUNC_INRANGE", + "DATE_ISO", "OBRACE", "CBRACE", "EQUAL", "UNEQUAL", "GT", "LT", "COMMA", "QUOTE", "AND", "OR", "$accept", "input", "line", "expr", "match", - "function", 0 + "function", "date", 0 }; #endif @@ -518,22 +526,22 @@ static const char *const yytname[] = static const yytype_uint16 yytoknum[] = { 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272 + 265, 266, 267, 268, 269, 270, 271 }; # endif /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 18, 19, 19, 20, 21, 21, 21, 21, 21, - 21, 21, 22, 22, 22, 22, 23 + 0, 17, 18, 18, 19, 20, 20, 20, 20, 20, + 20, 20, 21, 21, 21, 21, 22, 23, 23 }; /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ static const yytype_uint8 yyr2[] = { 0, 2, 0, 2, 1, 1, 3, 1, 1, 3, - 3, 3, 5, 5, 5, 5, 14 + 3, 3, 5, 5, 5, 5, 8, 4, 1 }; /* YYDEFACT[STATE-NAME] -- Default reduction number in state STATE-NUM. @@ -544,32 +552,32 @@ static const yytype_uint8 yydefact[] = 2, 0, 1, 0, 5, 0, 0, 3, 4, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 10, 11, 6, 0, - 0, 0, 0, 0, 12, 13, 15, 14, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 16 + 0, 0, 0, 0, 12, 13, 15, 14, 18, 0, + 0, 0, 0, 0, 0, 17, 16 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int8 yydefgoto[] = { - -1, 1, 7, 8, 9, 10 + -1, 1, 7, 8, 9, 10, 40 }; /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing STATE-NUM. */ -#define YYPACT_NINF -15 +#define YYPACT_NINF -10 static const yytype_int8 yypact[] = { - -15, 1, -15, 12, -15, -4, 13, -15, -14, -7, - -15, -2, 5, 11, 14, 10, -1, 13, 13, 23, - 24, 26, 27, 28, 19, -15, 17, -15, -15, 20, - 21, 22, 25, 31, -15, -15, -15, -15, 33, 36, - 34, 30, 35, 37, 43, 38, 39, -15 + -10, 10, -10, 9, -10, -2, -1, -10, 8, -9, + -10, 2, 12, 13, 14, 26, -7, -1, -1, 27, + 28, 29, 30, 31, 22, -10, 20, -10, -10, 23, + 24, 25, 32, 19, -10, -10, -10, -10, -10, 33, + 34, 38, 19, 35, 36, -10, -10 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int8 yypgoto[] = { - -15, -15, -15, -6, 32, -15 + -10, -10, -10, -6, 37, -10, 0 }; /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If @@ -578,39 +586,39 @@ static const yytype_int8 yypgoto[] = #define YYTABLE_NINF -1 static const yytype_uint8 yytable[] = { - 16, 2, 17, 18, 15, 3, 4, 5, 25, 6, - 19, 26, 27, 20, 24, 17, 18, 3, 4, 5, - 21, 6, 11, 12, 13, 14, 22, 3, 29, 23, - 30, 31, 32, 33, 18, 34, 35, 36, 38, 40, - 37, 39, 43, 41, 42, 44, 45, 46, 47, 0, - 0, 28 + 16, 25, 3, 4, 5, 15, 6, 19, 17, 18, + 2, 26, 27, 3, 4, 5, 20, 6, 11, 12, + 13, 14, 38, 17, 18, 39, 21, 22, 23, 24, + 3, 29, 30, 31, 32, 33, 18, 34, 35, 36, + 41, 43, 44, 45, 46, 0, 37, 42, 0, 0, + 0, 0, 0, 0, 0, 0, 28 }; #define yypact_value_is_default(yystate) \ - ((yystate) == (-15)) + ((yystate) == (-10)) #define yytable_value_is_error(yytable_value) \ YYID (0) static const yytype_int8 yycheck[] = { - 6, 0, 16, 17, 8, 4, 5, 6, 9, 8, - 17, 17, 18, 15, 4, 16, 17, 4, 5, 6, - 15, 8, 10, 11, 12, 13, 15, 4, 4, 15, - 4, 4, 4, 14, 17, 15, 15, 15, 7, 3, - 15, 8, 7, 9, 14, 8, 3, 9, 9, -1, - -1, 19 + 6, 8, 3, 4, 5, 7, 7, 16, 15, 16, + 0, 17, 18, 3, 4, 5, 14, 7, 9, 10, + 11, 12, 3, 15, 16, 6, 14, 14, 14, 3, + 3, 3, 3, 3, 3, 13, 16, 14, 14, 14, + 7, 3, 42, 8, 8, -1, 14, 13, -1, -1, + -1, -1, -1, -1, -1, -1, 19 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 19, 0, 4, 5, 6, 8, 20, 21, 22, - 23, 10, 11, 12, 13, 8, 21, 16, 17, 17, - 15, 15, 15, 15, 4, 9, 21, 21, 22, 4, - 4, 4, 4, 14, 15, 15, 15, 15, 7, 8, - 3, 9, 14, 7, 8, 3, 9, 9 + 0, 18, 0, 3, 4, 5, 7, 19, 20, 21, + 22, 9, 10, 11, 12, 7, 20, 15, 16, 16, + 14, 14, 14, 14, 3, 8, 20, 20, 21, 3, + 3, 3, 3, 13, 14, 14, 14, 14, 3, 6, + 23, 7, 13, 3, 23, 8, 8 }; #define yyerrok (yyerrstatus = 0) @@ -1447,7 +1455,7 @@ yyreduce: case 4: /* Line 1806 of yacc.c */ -#line 63 "spotlight_rawquery_parser.y" +#line 73 "spotlight_rawquery_parser.y" { ssp_result = talloc_asprintf(ssp_slq, "SELECT DISTINCT ?url WHERE " @@ -1460,7 +1468,7 @@ yyreduce: case 5: /* Line 1806 of yacc.c */ -#line 73 "spotlight_rawquery_parser.y" +#line 83 "spotlight_rawquery_parser.y" { if ((yyvsp[(1) - (1)].bval) == false) YYACCEPT; @@ -1472,7 +1480,7 @@ yyreduce: case 6: /* Line 1806 of yacc.c */ -#line 79 "spotlight_rawquery_parser.y" +#line 89 "spotlight_rawquery_parser.y" { if (strcmp((yyvsp[(1) - (3)].sval), (yyvsp[(3) - (3)].sval)) != 0) (yyval.sval) = talloc_asprintf(ssp_slq, "{ %s } UNION { %s }", (yyvsp[(1) - (3)].sval), (yyvsp[(3) - (3)].sval)); @@ -1484,35 +1492,35 @@ yyreduce: case 7: /* Line 1806 of yacc.c */ -#line 85 "spotlight_rawquery_parser.y" +#line 95 "spotlight_rawquery_parser.y" {(yyval.sval) = (yyvsp[(1) - (1)].sval); if ((yyval.sval) == NULL) YYABORT;} break; case 8: /* Line 1806 of yacc.c */ -#line 86 "spotlight_rawquery_parser.y" +#line 96 "spotlight_rawquery_parser.y" {(yyval.sval) = (yyvsp[(1) - (1)].sval);} break; case 9: /* Line 1806 of yacc.c */ -#line 87 "spotlight_rawquery_parser.y" +#line 97 "spotlight_rawquery_parser.y" {(yyval.sval) = talloc_asprintf(ssp_slq, "%s", (yyvsp[(2) - (3)].sval));} break; case 10: /* Line 1806 of yacc.c */ -#line 88 "spotlight_rawquery_parser.y" +#line 98 "spotlight_rawquery_parser.y" {(yyval.sval) = talloc_asprintf(ssp_slq, "%s . %s", (yyvsp[(1) - (3)].sval), (yyvsp[(3) - (3)].sval));} break; case 11: /* Line 1806 of yacc.c */ -#line 89 "spotlight_rawquery_parser.y" +#line 99 "spotlight_rawquery_parser.y" { if (strcmp((yyvsp[(1) - (3)].sval), (yyvsp[(3) - (3)].sval)) != 0) (yyval.sval) = talloc_asprintf(ssp_slq, "{ %s } UNION { %s }", (yyvsp[(1) - (3)].sval), (yyvsp[(3) - (3)].sval)); @@ -1524,42 +1532,56 @@ yyreduce: case 12: /* Line 1806 of yacc.c */ -#line 98 "spotlight_rawquery_parser.y" +#line 108 "spotlight_rawquery_parser.y" {(yyval.sval) = map_expr((yyvsp[(1) - (5)].sval), '=', (yyvsp[(4) - (5)].sval));} break; case 13: /* Line 1806 of yacc.c */ -#line 99 "spotlight_rawquery_parser.y" +#line 109 "spotlight_rawquery_parser.y" {(yyval.sval) = map_expr((yyvsp[(1) - (5)].sval), '!', (yyvsp[(4) - (5)].sval));} break; case 14: /* Line 1806 of yacc.c */ -#line 100 "spotlight_rawquery_parser.y" +#line 110 "spotlight_rawquery_parser.y" {(yyval.sval) = map_expr((yyvsp[(1) - (5)].sval), '<', (yyvsp[(4) - (5)].sval));} break; case 15: /* Line 1806 of yacc.c */ -#line 101 "spotlight_rawquery_parser.y" +#line 111 "spotlight_rawquery_parser.y" {(yyval.sval) = map_expr((yyvsp[(1) - (5)].sval), '>', (yyvsp[(4) - (5)].sval));} break; case 16: /* Line 1806 of yacc.c */ -#line 105 "spotlight_rawquery_parser.y" - {(yyval.sval) = map_daterange((yyvsp[(3) - (14)].sval), (yyvsp[(7) - (14)].sval), (yyvsp[(12) - (14)].sval));} +#line 115 "spotlight_rawquery_parser.y" + {(yyval.sval) = map_daterange((yyvsp[(3) - (8)].sval), (yyvsp[(5) - (8)].tval), (yyvsp[(7) - (8)].tval));} + break; + + case 17: + +/* Line 1806 of yacc.c */ +#line 119 "spotlight_rawquery_parser.y" + {(yyval.tval) = isodate2unix((yyvsp[(3) - (4)].sval));} + break; + + case 18: + +/* Line 1806 of yacc.c */ +#line 120 "spotlight_rawquery_parser.y" + {(yyval.tval) = atoi((yyvsp[(1) - (1)].sval)) + SPRAW_TIME_OFFSET;} break; /* Line 1806 of yacc.c */ -#line 1563 "spotlight_rawquery_parser.c" +#line 1585 "spotlight_rawquery_parser.c" default: break; } /* User semantic actions sometimes alter yychar, and that requires @@ -1790,25 +1812,44 @@ yyreturn: /* Line 2067 of yacc.c */ -#line 108 "spotlight_rawquery_parser.y" +#line 123 "spotlight_rawquery_parser.y" -const char *map_daterange(const char *dateattr, const char *date1, const char *date2) +static time_t isodate2unix(const char *s) { + struct tm tm; + + if (strptime(s, "%Y-%m-%dT%H:%M:%SZ", &tm) == NULL) + return (time_t)-1; + return mktime(&tm); +} + +const char *map_daterange(const char *dateattr, time_t date1, time_t date2) +{ + EC_INIT; char *result = NULL; struct spotlight_sparql_map *p; + struct tm *tmp; + char buf1[64], buf2[64]; + + EC_NULL( tmp = localtime(&date1) ); + strftime(buf1, sizeof(buf1), "%Y-%m-%dT%H:%M:%SZ", tmp); + EC_NULL( tmp = localtime(&date2) ); + strftime(buf2, sizeof(buf2), "%Y-%m-%dT%H:%M:%SZ", tmp); for (p = spotlight_sparql_map; p->ssm_spotlight_attr; p++) { if (strcmp(dateattr, p->ssm_spotlight_attr) == 0) { result = talloc_asprintf(ssp_slq, "?x %s ?d FILTER (?d > '%s' && ?d < '%s')", p->ssm_sparql_attr, - date1, - date2); + buf1, + buf2); } } - +EC_CLEANUP: + if (ret != 0) + return NULL; return result; } @@ -1817,6 +1858,9 @@ const char *map_expr(const char *attr, char op, const char *val) EC_INIT; char *result = NULL; struct spotlight_sparql_map *p; + time_t t; + struct tm *tmp; + char buf1[64]; for (p = spotlight_sparql_map; p->ssm_spotlight_attr; p++) { if (strcmp(p->ssm_spotlight_attr, attr) == 0) { @@ -1834,8 +1878,11 @@ const char *map_expr(const char *attr, char op, const char *val) result = talloc_asprintf(ssp_slq, "?x %s '%s'", p->ssm_sparql_attr, val); break; case ssmt_date: - yyerror("enexpected ssmt_date"); - EC_FAIL; + t = atoi(val) + SPRAW_TIME_OFFSET; + EC_NULL( tmp = localtime(&t) ); + strftime(buf1, sizeof(buf1), "%Y-%m-%dT%H:%M:%SZ", tmp); + result = talloc_asprintf(ssp_slq, "?x %s ?y FILTER(?y %c '%s')", p->ssm_sparql_attr, op, buf1); + break; default: yyerror("unknown Spotlight attribute type"); EC_FAIL; diff --git a/etc/afpd/spotlight_rawquery_parser.h b/etc/afpd/spotlight_rawquery_parser.h index 09294aed..33199c06 100644 --- a/etc/afpd/spotlight_rawquery_parser.h +++ b/etc/afpd/spotlight_rawquery_parser.h @@ -37,39 +37,37 @@ /* Put the tokens into the symbol table, so that GDB and other debuggers know about them. */ enum yytokentype { - DATE = 258, - WORD = 259, - BOOL = 260, - FUNC_INRANGE = 261, - DATE_SPEC = 262, - OBRACE = 263, - CBRACE = 264, - EQUAL = 265, - UNEQUAL = 266, - GT = 267, - LT = 268, - COMMA = 269, - QUOTE = 270, - AND = 271, - OR = 272 + WORD = 258, + BOOL = 259, + FUNC_INRANGE = 260, + DATE_ISO = 261, + OBRACE = 262, + CBRACE = 263, + EQUAL = 264, + UNEQUAL = 265, + GT = 266, + LT = 267, + COMMA = 268, + QUOTE = 269, + AND = 270, + OR = 271 }; #endif /* Tokens. */ -#define DATE 258 -#define WORD 259 -#define BOOL 260 -#define FUNC_INRANGE 261 -#define DATE_SPEC 262 -#define OBRACE 263 -#define CBRACE 264 -#define EQUAL 265 -#define UNEQUAL 266 -#define GT 267 -#define LT 268 -#define COMMA 269 -#define QUOTE 270 -#define AND 271 -#define OR 272 +#define WORD 258 +#define BOOL 259 +#define FUNC_INRANGE 260 +#define DATE_ISO 261 +#define OBRACE 262 +#define CBRACE 263 +#define EQUAL 264 +#define UNEQUAL 265 +#define GT 266 +#define LT 267 +#define COMMA 268 +#define QUOTE 269 +#define AND 270 +#define OR 271 @@ -79,16 +77,17 @@ typedef union YYSTYPE { /* Line 2068 of yacc.c */ -#line 37 "spotlight_rawquery_parser.y" +#line 45 "spotlight_rawquery_parser.y" int ival; const char *sval; bool bval; + time_t tval; /* Line 2068 of yacc.c */ -#line 92 "spotlight_rawquery_parser.h" +#line 91 "spotlight_rawquery_parser.h" } YYSTYPE; # define YYSTYPE_IS_TRIVIAL 1 # define yystype YYSTYPE /* obsolescent; will be withdrawn */ @@ -101,8 +100,9 @@ extern YYSTYPE yylval; /* "%code provides" blocks. */ /* Line 2068 of yacc.c */ -#line 32 "spotlight_rawquery_parser.y" +#line 39 "spotlight_rawquery_parser.y" + #define SPRAW_TIME_OFFSET 978307200 extern int map_spotlight_to_sparql_query(slq_t *slq, gchar **sparql_result); extern slq_t *ssp_slq; diff --git a/etc/afpd/spotlight_rawquery_parser.y b/etc/afpd/spotlight_rawquery_parser.y index 7f8bf6b9..8dc36032 100644 --- a/etc/afpd/spotlight_rawquery_parser.y +++ b/etc/afpd/spotlight_rawquery_parser.y @@ -1,11 +1,17 @@ %{ + #include + #include #include #include + #include + #include + #include #include #include + #include "spotlight_SPARQL_map.h" #include "spotlight.h" @@ -19,9 +25,10 @@ /* forward declarations */ static const char *map_expr(const char *attr, char op, const char *val); - static const char *map_daterange(const char *dateattr, const char *date1, const char *date2); - - /* global vars, eg needed by the lexer */ + static const char *map_daterange(const char *dateattr, time_t date1, time_t date2); + static time_t isodate2unix(const char *s); + + /* global vars, eg needed by the lexer */ slq_t *ssp_slq; /* local vars */ @@ -30,6 +37,7 @@ %} %code provides { + #define SPRAW_TIME_OFFSET 978307200 extern int map_spotlight_to_sparql_query(slq_t *slq, gchar **sparql_result); extern slq_t *ssp_slq; } @@ -38,17 +46,19 @@ int ival; const char *sval; bool bval; + time_t tval; } %expect 1 %error-verbose %type match expr line function -%token DATE +%type date + %token WORD %token BOOL %token FUNC_INRANGE -%token DATE_SPEC +%token DATE_ISO %token OBRACE CBRACE EQUAL UNEQUAL GT LT COMMA QUOTE %left AND %left OR @@ -102,27 +112,51 @@ WORD EQUAL QUOTE WORD QUOTE {$$ = map_expr($1, '=', $4);} ; function: -FUNC_INRANGE OBRACE WORD COMMA DATE_SPEC OBRACE DATE CBRACE COMMA DATE_SPEC OBRACE DATE CBRACE CBRACE {$$ = map_daterange($3, $7, $12);} +FUNC_INRANGE OBRACE WORD COMMA date COMMA date CBRACE {$$ = map_daterange($3, $5, $7);} +; + +date: +DATE_ISO OBRACE WORD CBRACE {$$ = isodate2unix($3);} +| WORD {$$ = atoi($1) + SPRAW_TIME_OFFSET;} ; %% -const char *map_daterange(const char *dateattr, const char *date1, const char *date2) +static time_t isodate2unix(const char *s) { + struct tm tm; + + if (strptime(s, "%Y-%m-%dT%H:%M:%SZ", &tm) == NULL) + return (time_t)-1; + return mktime(&tm); +} + +const char *map_daterange(const char *dateattr, time_t date1, time_t date2) +{ + EC_INIT; char *result = NULL; struct spotlight_sparql_map *p; + struct tm *tmp; + char buf1[64], buf2[64]; + + EC_NULL( tmp = localtime(&date1) ); + strftime(buf1, sizeof(buf1), "%Y-%m-%dT%H:%M:%SZ", tmp); + EC_NULL( tmp = localtime(&date2) ); + strftime(buf2, sizeof(buf2), "%Y-%m-%dT%H:%M:%SZ", tmp); for (p = spotlight_sparql_map; p->ssm_spotlight_attr; p++) { if (strcmp(dateattr, p->ssm_spotlight_attr) == 0) { result = talloc_asprintf(ssp_slq, "?x %s ?d FILTER (?d > '%s' && ?d < '%s')", p->ssm_sparql_attr, - date1, - date2); + buf1, + buf2); } } - +EC_CLEANUP: + if (ret != 0) + return NULL; return result; } @@ -131,6 +165,9 @@ const char *map_expr(const char *attr, char op, const char *val) EC_INIT; char *result = NULL; struct spotlight_sparql_map *p; + time_t t; + struct tm *tmp; + char buf1[64]; for (p = spotlight_sparql_map; p->ssm_spotlight_attr; p++) { if (strcmp(p->ssm_spotlight_attr, attr) == 0) { @@ -148,8 +185,11 @@ const char *map_expr(const char *attr, char op, const char *val) result = talloc_asprintf(ssp_slq, "?x %s '%s'", p->ssm_sparql_attr, val); break; case ssmt_date: - yyerror("enexpected ssmt_date"); - EC_FAIL; + t = atoi(val) + SPRAW_TIME_OFFSET; + EC_NULL( tmp = localtime(&t) ); + strftime(buf1, sizeof(buf1), "%Y-%m-%dT%H:%M:%SZ", tmp); + result = talloc_asprintf(ssp_slq, "?x %s ?y FILTER(?y %c '%s')", p->ssm_sparql_attr, op, buf1); + break; default: yyerror("unknown Spotlight attribute type"); EC_FAIL; -- 2.39.2