]> arthur.barton.de Git - netatalk.git/blob - etc/afpd/spotlight_rawquery_parser.y
792ea95de6988dbb4701ae465e6f38cb099ee9f9
[netatalk.git] / etc / afpd / spotlight_rawquery_parser.y
1 %{
2   #include <stdbool.h>
3   #include <stdio.h>
4   #include <string.h>
5   #include <gio/gio.h>
6   #include <atalk/talloc.h>
7   #include <atalk/logger.h>
8   #include "spotlight_SPARQL_map.h"
9   #include "spotlight.h"
10
11   struct yy_buffer_state;
12   typedef struct yy_buffer_state *YY_BUFFER_STATE;
13   extern int yylex (void);
14   extern void yyerror (char const *);
15   extern void *yyterminate(void);
16   extern YY_BUFFER_STATE yy_scan_string( const char *str);
17   extern void yy_delete_buffer ( YY_BUFFER_STATE buffer );
18
19   static const char *map_expr(const char *attr, const char *val);
20   static const char *map_daterange(const char *dateattr, const char *date1, const char *date2);
21
22   slq_t *ssp_slq;
23   gchar *ssp_result;
24
25 %}
26
27 %code provides {
28   extern const gchar *map_spotlight_to_sparql_query(slq_t *slq);
29   extern slq_t *ssp_slq;
30   extern gchar *ssp_result;
31 }
32
33 %union {
34     int ival;
35     const char *sval;
36 }
37
38 %expect 1
39 %error-verbose
40
41 %type <sval> match expr line function
42 %token <sval> DATE
43 %token <sval> WORD
44 %token FUNC_INRANGE
45 %token DATE_SPEC
46 %token OBRACE CBRACE EQUAL COMMA QUOTE
47 %left AND
48 %left OR
49 %%
50
51 input:
52 /* empty */
53 | input line
54 ;
55      
56 line:
57 expr                           {
58     ssp_result = talloc_asprintf(ssp_slq,
59                                  "SELECT DISTINCT ?url WHERE "
60                                  "{ ?x nie:url ?url FILTER(fn:starts-with(?url, 'file://%s/')) . %s}",
61                                  ssp_slq->slq_vol->v_path, $1);
62     $$ = ssp_result;
63 }
64 ;
65
66 expr:
67 match OR match                 {
68     if (strcmp($1, $3) != 0)
69         $$ = talloc_asprintf(ssp_slq, "{ %s } UNION { %s }", $1, $3);
70     else
71         $$ = talloc_asprintf(ssp_slq, "%s", $1);
72 }
73 | match                        {$$ = $1;}
74 | function                     {$$ = $1;}
75 | OBRACE expr CBRACE           {$$ = talloc_asprintf(ssp_slq, "%s", $2);}
76 | expr AND expr                {$$ = talloc_asprintf(ssp_slq, "%s . %s", $1, $3);}
77 | expr OR expr                 {
78     if (strcmp($1, $3) != 0)
79         $$ = talloc_asprintf(ssp_slq, "{ %s } UNION { %s }", $1, $3);
80     else
81         $$ = talloc_asprintf(ssp_slq, "%s", $1);
82 }
83 ;
84
85 match:
86 WORD EQUAL QUOTE WORD QUOTE    {$$ = map_expr($1, $4);}
87 ;
88
89 function:
90 FUNC_INRANGE OBRACE WORD COMMA DATE_SPEC OBRACE DATE CBRACE COMMA DATE_SPEC OBRACE DATE CBRACE CBRACE {$$ = map_daterange($3, $7, $12);}
91 ;
92
93 %%
94
95 const char *map_daterange(const char *dateattr, const char *date1, const char *date2)
96 {
97     char *result = NULL;
98     struct spotlight_sparql_map *p;
99
100     for (p = spotlight_sparql_map; p->ssm_spotlight_attr; p++) {
101         if (strcmp(dateattr, p->ssm_spotlight_attr) == 0) {
102             result = talloc_asprintf(ssp_slq,
103                                      "?x %s ?d FILTER (?d > '%s' && ?d < '%s')",
104                                      p->ssm_sparql_attr,
105                                      date1,
106                                      date2);
107         }
108     }
109
110
111     return result;
112 }
113
114 const char *map_expr(const char *attr, const char *val)
115 {
116     char *result = NULL;
117     struct spotlight_sparql_map *p;
118
119     for (p = spotlight_sparql_map; p->ssm_spotlight_attr; p++) {
120         if (strcmp(p->ssm_spotlight_attr, attr) == 0) {
121             result = talloc_asprintf(ssp_slq, p->ssm_sparql_query_fmtstr, val);
122             break;
123         }
124     }
125
126     return result;
127 }
128
129 void yyerror(const char *str)
130 {
131 #ifdef MAIN
132     printf("yyerror: %s\n", str);
133 #else
134     LOG(log_error, logtype_sl, "yyerror: %s", str);
135 #endif
136 }
137  
138 int yywrap()
139 {
140     return 1;
141
142
143 const gchar *map_spotlight_to_sparql_query(slq_t *slq)
144 {
145     YY_BUFFER_STATE s;
146
147     ssp_slq = slq;
148     s = yy_scan_string(slq->slq_qstring);
149
150     LOG(log_debug, logtype_sl, "map_spotlight_to_sparql_query: %s", slq->slq_qstring);
151
152     yyparse();
153     yy_delete_buffer(s);
154
155     return ssp_result;
156 }
157
158 #ifdef MAIN
159 int main(int argc, char **argv)
160 {
161     YY_BUFFER_STATE s;
162
163     if (argc != 2) {
164         printf("usage: %s QUERY\n", argv[0]);
165         return 1;
166     }
167
168     ssp_slq = talloc_zero(NULL, slq_t);
169     struct vol *vol = talloc_zero(ssp_slq, struct vol);
170     vol->v_path = "/Volumes/test";
171     ssp_slq->slq_vol = vol;
172
173     s = yy_scan_string(argv[1]);
174
175     yyparse();
176
177     yy_delete_buffer(s);
178
179     printf("SPARQL: %s\n", ssp_result);
180
181     return 0;
182
183 #endif