From: Frank Lahm Date: Thu, 1 Nov 2012 14:04:21 +0000 (+0100) Subject: Better parsing X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=commitdiff_plain;h=0514aeef6f0102e4f7d274f0c0046003eca5c6c1 Better parsing --- diff --git a/etc/afpd/spotlight_SPARQL_map.c b/etc/afpd/spotlight_SPARQL_map.c index 553e7639..d69b7a31 100644 --- a/etc/afpd/spotlight_SPARQL_map.c +++ b/etc/afpd/spotlight_SPARQL_map.c @@ -21,12 +21,14 @@ #include "spotlight_SPARQL_map.h" struct spotlight_sparql_map spotlight_sparql_map[] = { -/* ssm_spotlight_attr ssm_sparql_attr ssm_sparql_query_fmtstr */ - {"*", "fts:match", "?x fts:match '%s'"}, - {"kMDItemTextContent", "fts:match", "?x fts:match '%s'"}, - {"kMDItemDisplayName", "nfo:fileName", "?x nfo:fileName ?y FILTER(regex(?y, '%s'))"}, - {"kMDItemContentCreationDate", "nfo:fileCreated", "?x nfo:fileCreated '%s'"}, - {"kMDItemFSContentChangeDate", "nfo:fileLastModified", "?x nfo:fileLastModified '%s'"}, - {"kMDItemContentModificationDate", "nfo:fileLastModified", "?x nfo:fileLastModified '%s'"}, - {NULL, NULL, NULL} +/* ssm_spotlight_attr ssm_type, ssm_sparql_attr */ + {"*", ssmt_fts, "fts:match"}, + {"kMDItemTextContent", ssmt_fts, "fts:match"}, + {"kMDItemDisplayName", ssmt_str, "nfo:fileName"}, + {"kMDItemContentCreationDate", ssmt_date, "nfo:fileCreated"}, + {"kMDItemFSContentChangeDate", ssmt_date, "nfo:fileLastModified"}, + {"kMDItemContentModificationDate", ssmt_date, "nfo:fileLastModified"}, + {"kMDItemPixelWidth", ssmt_num, "nfo:width"}, + {"kMDItemPixelHeight", ssmt_num, "nfo:height"}, + {NULL, ssmt_str, NULL} }; diff --git a/etc/afpd/spotlight_SPARQL_map.h b/etc/afpd/spotlight_SPARQL_map.h index 582b9ae1..1ea6736f 100644 --- a/etc/afpd/spotlight_SPARQL_map.h +++ b/etc/afpd/spotlight_SPARQL_map.h @@ -19,10 +19,18 @@ #ifndef SPOTLIGHT_SPARQL_MAP_H #define SPOTLIGHT_SPARQL_MAP_H +enum ssm_type { + ssmt_bool, /* a boolean value that doesn't requires a SPARQL FILTER */ + ssmt_num, /* a numeric value that requires a SPARQL FILTER */ + ssmt_str, /* a string value that requieres a SPARQL FILTER */ + ssmt_fts, /* a string value that will be queried with SPARQL 'fts:match' */ + ssmt_date /* date values are handled in a special map function map_daterange() */ +}; + struct spotlight_sparql_map { const char *ssm_spotlight_attr; + enum ssm_type ssm_type; const char *ssm_sparql_attr; - const char *ssm_sparql_query_fmtstr; }; extern struct spotlight_sparql_map spotlight_sparql_map[]; diff --git a/etc/afpd/spotlight_module.c b/etc/afpd/spotlight_module.c index 5369319c..efa814d3 100644 --- a/etc/afpd/spotlight_module.c +++ b/etc/afpd/spotlight_module.c @@ -121,11 +121,11 @@ static int sl_mod_start_search(void *p) gchar *sparql_query; GError *error = NULL; - LOG(log_debug, logtype_sl, "sl_mod_start_search: Spotlight query string: \"%s\"", slq->slq_qstring); + LOG(log_info, logtype_sl, "sl_mod_start_search: Spotlight query string: \"%s\"", slq->slq_qstring); EC_ZERO_LOGSTR( map_spotlight_to_sparql_query(slq, &sparql_query), "Mapping Spotlight query failed: \"%s\"", slq->slq_qstring ); - LOG(log_debug, logtype_sl, "sl_mod_start_search: SPARQL query: \"%s\"", sparql_query); + LOG(log_info, logtype_sl, "sl_mod_start_search: SPARQL query: \"%s\"", sparql_query); #if 0 /* Start the async query */ diff --git a/etc/afpd/spotlight_rawquery_lexer.c b/etc/afpd/spotlight_rawquery_lexer.c index 59c123b5..05f1bdc2 100644 --- a/etc/afpd/spotlight_rawquery_lexer.c +++ b/etc/afpd/spotlight_rawquery_lexer.c @@ -370,12 +370,12 @@ struct yy_trans_info }; static yyconst flex_int16_t yy_accept[75] = { 0, - 0, 0, 21, 20, 17, 17, 20, 7, 20, 20, - 8, 9, 6, 16, 14, 20, 15, 6, 6, 6, - 6, 20, 0, 13, 0, 10, 6, 12, 6, 6, - 6, 6, 6, 11, 0, 0, 6, 6, 6, 6, - 6, 0, 0, 6, 6, 6, 5, 0, 0, 6, - 6, 4, 0, 0, 6, 0, 0, 1, 0, 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 } ; @@ -386,8 +386,8 @@ static yyconst flex_int32_t yy_ec[256] = 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, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 14, 1, 15, + 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, @@ -819,80 +819,80 @@ YY_RULE_SETUP case 4: YY_RULE_SETUP #line 14 "spotlight_rawquery_lexer.l" -{yylval.bval = false; return BOOL;} +/* ignore case specifier */ YY_BREAK case 5: YY_RULE_SETUP #line 15 "spotlight_rawquery_lexer.l" -{yylval.bval = true; return BOOL;} +/* ignore */ YY_BREAK case 6: YY_RULE_SETUP #line 16 "spotlight_rawquery_lexer.l" -{yylval.sval = talloc_strdup(ssp_slq, yytext); return WORD;} +{yylval.bval = false; return BOOL;} YY_BREAK case 7: YY_RULE_SETUP #line 17 "spotlight_rawquery_lexer.l" -return QUOTE; +{yylval.bval = true; return BOOL;} YY_BREAK case 8: YY_RULE_SETUP #line 18 "spotlight_rawquery_lexer.l" -return OBRACE; +{yylval.sval = talloc_strdup(ssp_slq, yytext); return WORD;} YY_BREAK case 9: YY_RULE_SETUP #line 19 "spotlight_rawquery_lexer.l" -return CBRACE; +return QUOTE; YY_BREAK case 10: YY_RULE_SETUP #line 20 "spotlight_rawquery_lexer.l" -return AND; +return OBRACE; YY_BREAK case 11: YY_RULE_SETUP #line 21 "spotlight_rawquery_lexer.l" -return OR; +return CBRACE; YY_BREAK case 12: YY_RULE_SETUP #line 22 "spotlight_rawquery_lexer.l" -return EQUAL; +return AND; YY_BREAK case 13: YY_RULE_SETUP #line 23 "spotlight_rawquery_lexer.l" -return UNEQUAL; +return OR; YY_BREAK case 14: YY_RULE_SETUP #line 24 "spotlight_rawquery_lexer.l" -return LT; +return EQUAL; YY_BREAK case 15: YY_RULE_SETUP #line 25 "spotlight_rawquery_lexer.l" -return GT; +return UNEQUAL; YY_BREAK case 16: YY_RULE_SETUP #line 26 "spotlight_rawquery_lexer.l" -return COMMA; +return LT; YY_BREAK case 17: -/* rule 17 can match eol */ YY_RULE_SETUP #line 27 "spotlight_rawquery_lexer.l" -/* ignore */ +return GT; YY_BREAK case 18: YY_RULE_SETUP #line 28 "spotlight_rawquery_lexer.l" -/* ignore case specifier */ +return COMMA; YY_BREAK case 19: +/* rule 19 can match eol */ YY_RULE_SETUP #line 29 "spotlight_rawquery_lexer.l" /* ignore */ diff --git a/etc/afpd/spotlight_rawquery_lexer.l b/etc/afpd/spotlight_rawquery_lexer.l index 6bc87e2c..b3b4bce2 100644 --- a/etc/afpd/spotlight_rawquery_lexer.l +++ b/etc/afpd/spotlight_rawquery_lexer.l @@ -11,9 +11,11 @@ InRange return FUNC_INRANGE; \$time\.iso return DATE_SPEC; ....-..-..T..:..:..Z {yylval.sval = talloc_strdup(ssp_slq, yytext); return DATE;} +cwd /* ignore case specifier */ +cd /* ignore */ false {yylval.bval = false; return BOOL;} true {yylval.bval = true; return BOOL;} -[a-zA-Z\*]+ {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; @@ -25,6 +27,4 @@ true {yylval.bval = true; return BOOL;} \> return GT; \, return COMMA; [ \t\n] /* ignore */ -cwd /* ignore case specifier */ -cd /* ignore */ %% diff --git a/etc/afpd/spotlight_rawquery_parser.c b/etc/afpd/spotlight_rawquery_parser.c index 1dbe989e..b4453de8 100644 --- a/etc/afpd/spotlight_rawquery_parser.c +++ b/etc/afpd/spotlight_rawquery_parser.c @@ -1485,7 +1485,7 @@ yyreduce: /* Line 1806 of yacc.c */ #line 85 "spotlight_rawquery_parser.y" - {(yyval.sval) = (yyvsp[(1) - (1)].sval);} + {(yyval.sval) = (yyvsp[(1) - (1)].sval); if ((yyval.sval) == NULL) YYABORT;} break; case 8: @@ -1814,16 +1814,37 @@ const char *map_daterange(const char *dateattr, const char *date1, const char *d const char *map_expr(const char *attr, char op, const char *val) { + EC_INIT; char *result = NULL; struct spotlight_sparql_map *p; for (p = spotlight_sparql_map; p->ssm_spotlight_attr; p++) { if (strcmp(p->ssm_spotlight_attr, attr) == 0) { - result = talloc_asprintf(ssp_slq, p->ssm_sparql_query_fmtstr, val); + switch (p->ssm_type) { + case ssmt_bool: + result = talloc_asprintf(ssp_slq, "?x %s '%s'", p->ssm_sparql_attr, val); + break; + case ssmt_num: + result = talloc_asprintf(ssp_slq, "?x %s ?y FILTER(?y %c '%s')", p->ssm_sparql_attr, op, val); + break; + case ssmt_str: + result = talloc_asprintf(ssp_slq, "?x %s ?y FILTER(regex(?y, '%s'))", p->ssm_sparql_attr, val); + break; + case ssmt_fts: + result = talloc_asprintf(ssp_slq, "?x %s '%s'", p->ssm_sparql_attr, val); + break; + case ssmt_date: + yyerror("enexpected ssmt_date"); + EC_FAIL; + default: + yyerror("unknown Spotlight attribute type"); + EC_FAIL; + } break; } } +EC_CLEANUP: return result; } @@ -1853,6 +1874,7 @@ int map_spotlight_to_sparql_query(slq_t *slq, gchar **sparql_result) { EC_INIT; YY_BUFFER_STATE s = NULL; + ssp_result = NULL; ssp_slq = slq; s = yy_scan_string(slq->slq_qstring); @@ -1863,9 +1885,9 @@ EC_CLEANUP: if (s) yy_delete_buffer(s); if (ret == 0) - *sparql_result = NULL; - else *sparql_result = ssp_result; + else + *sparql_result = NULL; EC_EXIT; } diff --git a/etc/afpd/spotlight_rawquery_parser.y b/etc/afpd/spotlight_rawquery_parser.y index daf5bc2f..7f8bf6b9 100644 --- a/etc/afpd/spotlight_rawquery_parser.y +++ b/etc/afpd/spotlight_rawquery_parser.y @@ -82,7 +82,7 @@ BOOL { else $$ = talloc_asprintf(ssp_slq, "%s", $1); } -| match {$$ = $1;} +| match {$$ = $1; if ($$ == NULL) YYABORT;} | function {$$ = $1;} | OBRACE expr CBRACE {$$ = talloc_asprintf(ssp_slq, "%s", $2);} | expr AND expr {$$ = talloc_asprintf(ssp_slq, "%s . %s", $1, $3);} @@ -128,18 +128,37 @@ const char *map_daterange(const char *dateattr, const char *date1, const char *d const char *map_expr(const char *attr, char op, const char *val) { + EC_INIT; char *result = NULL; struct spotlight_sparql_map *p; for (p = spotlight_sparql_map; p->ssm_spotlight_attr; p++) { -#if 0 if (strcmp(p->ssm_spotlight_attr, attr) == 0) { - result = talloc_asprintf(ssp_slq, p->ssm_sparql_query_fmtstr, val); + switch (p->ssm_type) { + case ssmt_bool: + result = talloc_asprintf(ssp_slq, "?x %s '%s'", p->ssm_sparql_attr, val); + break; + case ssmt_num: + result = talloc_asprintf(ssp_slq, "?x %s ?y FILTER(?y %c '%s')", p->ssm_sparql_attr, op, val); + break; + case ssmt_str: + result = talloc_asprintf(ssp_slq, "?x %s ?y FILTER(regex(?y, '%s'))", p->ssm_sparql_attr, val); + break; + case ssmt_fts: + result = talloc_asprintf(ssp_slq, "?x %s '%s'", p->ssm_sparql_attr, val); + break; + case ssmt_date: + yyerror("enexpected ssmt_date"); + EC_FAIL; + default: + yyerror("unknown Spotlight attribute type"); + EC_FAIL; + } break; } -#endif } +EC_CLEANUP: return result; } @@ -169,6 +188,7 @@ int map_spotlight_to_sparql_query(slq_t *slq, gchar **sparql_result) { EC_INIT; YY_BUFFER_STATE s = NULL; + ssp_result = NULL; ssp_slq = slq; s = yy_scan_string(slq->slq_qstring); @@ -179,9 +199,9 @@ EC_CLEANUP: if (s) yy_delete_buffer(s); if (ret == 0) - *sparql_result = NULL; - else *sparql_result = ssp_result; + else + *sparql_result = NULL; EC_EXIT; }