dav/sync.c

changeset 396
1490c24c6077
parent 395
b491d207ee16
child 397
ddda42712f39
equal deleted inserted replaced
395:b491d207ee16 396:1490c24c6077
280 280
281 size_t consumed = rtrimskip(fs, 0); 281 size_t consumed = rtrimskip(fs, 0);
282 fs = sstrsubs(fs, consumed); 282 fs = sstrsubs(fs, consumed);
283 283
284 if (fs.length == 0) { 284 if (fs.length == 0) {
285 memset(tagfilter, 0, sizeof(SyncTagFilter));
286 return consumed; 285 return consumed;
287 } else { 286 } else {
288 287
289 // optional operator 288 // optional operator
290 int hasop = 0; 289 int hasop = 0;
310 consumed += skip; 309 consumed += skip;
311 fs = sstrsubs(fs, skip); 310 fs = sstrsubs(fs, skip);
312 } 311 }
313 312
314 if (fs.length > 0 && fs.ptr[0] == '(') { 313 if (fs.length > 0 && fs.ptr[0] == '(') {
315 consumed += parse_tagfilter_subfilters(fs, tagfilter); 314 size_t c = parse_tagfilter_subfilters(fs, tagfilter);
315 if (c) {
316 return consumed + c;
317 } else {
318 return 0;
319 }
316 } else { 320 } else {
317 tagfilter->subfilter_count = 0; 321 tagfilter->subfilter_count = 0;
318 tagfilter->subfilters = NULL; 322 tagfilter->subfilters = NULL;
319 consumed += parse_tagfilter_taglist(fs, tagfilter); 323 return consumed + parse_tagfilter_taglist(fs, tagfilter);
320 } 324 }
321
322 return consumed;
323 } 325 }
324 } 326 }
325 327
326 /* 328 /*
327 * Parses: ( "(" , filter , ")" )+ 329 * Parses: ( "(" , filter , ")" )+
328 */ 330 */
329 static size_t parse_tagfilter_subfilters(sstr_t fs, SyncTagFilter* tagfilter) { 331 static size_t parse_tagfilter_subfilters(sstr_t fs, SyncTagFilter* f) {
330 // TODO: implement 332
331 tagfilter->subfilter_count = 0; 333 // strategy: allocate much and give back later (instead of reallocs in loop)
332 tagfilter->subfilters = NULL; 334 size_t subfilter_cap = 8;
333 335 f->subfilters = calloc(subfilter_cap, sizeof(SyncTagFilter*));
334 return 0; 336 f->subfilter_count = 0;
337
338 size_t total_consumed = 0;
339 size_t c;
340 do {
341 // skip leading parenthesis (and white spaces)
342 c = rtrimskip(fs, 1);
343 fs = sstrsubs(fs, c);
344 total_consumed += c;
345
346 // increase array capacity, if necessary
347 if (f->subfilter_count >= subfilter_cap) {
348 subfilter_cap *= 2;
349 SyncTagFilter** newarr = realloc(f->subfilters,
350 subfilter_cap * sizeof(SyncTagFilter*));
351 if (newarr) {
352 f->subfilters = newarr;
353 } else {
354 abort(); // no error handling reachable, so we are fucked
355 }
356 }
357
358 // allocate space for a new filter
359 SyncTagFilter* subf = calloc(1, sizeof(SyncTagFilter));
360
361 // parse that filter
362 c = parse_tagfilter_filter(fs, subf);
363
364 // sanity check: we must end with a closing parenthesis
365 if (c > 0 && fs.ptr[c] == ')') {
366 f->subfilters[f->subfilter_count++] = subf;
367
368 // consume ')' and find the next parenthesis or the end-of-string
369 c = rtrimskip(fs, 1+c);
370 fs = sstrsubs(fs, c);
371 total_consumed += c;
372
373 if (fs.length == 0 || fs.ptr[0] == ')') {
374 // our job is done
375 break;
376 } else if (fs.ptr[0] != '(') {
377 // anything else than a parenthesis or end-of-string is an error
378 return 0;
379 }
380 } else {
381 free(subf);
382 break;
383 }
384
385 } while(1);
386
387 // try to shrink the array
388 if (f->subfilter_count > 0) {
389 SyncTagFilter** shrinked_array = realloc(f->subfilters,
390 f->subfilter_count * sizeof(SyncTagFilter*));
391 if (shrinked_array) {
392 f->subfilters = shrinked_array;
393 }
394 } else {
395 free(f->subfilters);
396 f->subfilters = NULL;
397 }
398
399 return total_consumed;
335 } 400 }
336 401
337 SyncTagFilter* parse_tagfilter_string(const char* filterstring) { 402 SyncTagFilter* parse_tagfilter_string(const char* filterstring) {
338 SyncTagFilter* tagfilter = malloc(sizeof(SyncTagFilter)); 403 SyncTagFilter* tagfilter = calloc(1, sizeof(SyncTagFilter));
339 if (!filterstring) { 404 if (!filterstring) {
340 memset(tagfilter, 0, sizeof(SyncTagFilter));
341 return tagfilter; 405 return tagfilter;
342 } 406 }
343 407
344 // TODO: use scstr_t after update to UCX 2.0 408 // TODO: use scstr_t after update to UCX 2.0
345 sstr_t fs = sstr((char*) filterstring); 409 sstr_t fs = sstr((char*) filterstring);
346 size_t consumed = parse_tagfilter_filter(fs, tagfilter); 410 size_t consumed = parse_tagfilter_filter(fs, tagfilter);
411 if (!consumed) {
412 free_tagfilter(tagfilter);
413 return NULL;
414 }
347 415
348 // consume trailing white spaces 416 // consume trailing white spaces
349 consumed = rtrimskip(fs, consumed); 417 consumed = rtrimskip(fs, consumed);
350 418
351 // sanity check: have we consumed the whole string? 419 // sanity check: have we consumed the whole string?

mercurial