]> arthur.barton.de Git - netatalk.git/commitdiff
Better parsing
authorFrank Lahm <franklahm@googlemail.com>
Thu, 1 Nov 2012 14:04:21 +0000 (15:04 +0100)
committerFrank Lahm <franklahm@googlemail.com>
Thu, 1 Nov 2012 14:04:21 +0000 (15:04 +0100)
etc/afpd/spotlight_SPARQL_map.c
etc/afpd/spotlight_SPARQL_map.h
etc/afpd/spotlight_module.c
etc/afpd/spotlight_rawquery_lexer.c
etc/afpd/spotlight_rawquery_lexer.l
etc/afpd/spotlight_rawquery_parser.c
etc/afpd/spotlight_rawquery_parser.y

index 553e7639c7a840a6bc47ae34399910d1171c846e..d69b7a31fd99c8bec4206c4ab0ad3b3a7b8bbd4d 100644 (file)
 #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}
 };
index 582b9ae132473d13c4f39eff95fcca165566c3c3..1ea6736fc47f057748ea791d5b65a3845f9dcef3 100644 (file)
 #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[];
index 5369319ce185eb5048dce8bd3ffa79164b41a1c1..efa814d33cd565dcbd304e871cdfdb97386223b9 100644 (file)
@@ -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 */
index 59c123b535b7425094655592bbeb7b96df30b42f..05f1bdc2081b353c144af3a19a94b114fd05701f 100644 (file)
@@ -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 */
index 6bc87e2c143d1c7d5b56f2787014dd7e174ebd9f..b3b4bce2729e3842a1efc643a92ddb22b3956c57 100644 (file)
 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 */
 %%
index 1dbe989ec5ab69efa101ce5d93f7ce6e27cb8003..b4453de89585ed952e86eae05839dd14e4cf7a62 100644 (file)
@@ -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;
 }
 
index daf5bc2ff7381fcb24792a5f73c3f61b8a23d924..7f8bf6b9e1da90b3bf4d0085cafd76abbfd144ff 100644 (file)
@@ -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;
 }