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