Не удается заставить метод C icalrecur_expand_recurrence работать

Это немного расстраивает. Я работал над этим некоторое время, и я не могу заставить этот метод работать так, как он говорит.

#include "icalrecur.h"
#include <time.h> /* for time() */
#include <stdio.h>

int get_occurrences(char* rrule, time_t start, int count)
{
        //char*        rule; /* rule string */
       // *rule = PG_GETARG_CHAR(0);

        time_t   *result[count]; /* output array */

        icalrecur_expand_recurrence(rrule, start, count, *result);

        return (time_t) *result;
}


//time_t *output[5*8];

void main() {
        time_t right_now = time(0);
        char *_rrule = "FREQ=WEEKLY;INTERVAL=2;COUNT=8;WKST=SU;BYDAY=TU,TH";
        get_occurrences(_rrule, right_now, 5);
}

Я сохраняю этот тестовый файл как ical_recur.h, Затем я набираю в bash:

gcc -I/usr/local/libical/include/libical -L/usr/local/libical/lib/ -lical -o hello ical_recur.c

Чтобы включить libical.a библиотеки. include/libical каталог имеет icalrecur.h в этом, так что мне даже не нужно включать целую библиотеку.

~: ./hello
Segmentation fault

Каждый раз, когда я меняю указатели, он начинает жаловаться на что-то во время компиляции. Кто-нибудь может заставить это работать?? Исходные файлы из Marketcircle на github.

2 ответа

Решение

Глядя на документацию, кажется, что у вас есть нежелательный дополнительный уровень косвенности - вам нужно изменить:

    time_t   *result[count]; /* output array */

    icalrecur_expand_recurrence(rrule, start, count, *result);

чтобы:

    time_t   result[count]; /* output array */

    icalrecur_expand_recurrence(rrule, start, count, result);

Также вы передаете строковый литерал только для чтения в функцию, которая ожидает char * - это должно по крайней мере дать вам предупреждение компилятора (подсказка: всегда используйте gcc -Wall ..., внимательно прочитайте предупреждения, поймите их и исправьте). main() должно выглядеть больше так:

int main() {
    time_t right_now = time(0);
    char _rrule[] = "FREQ=WEEKLY;INTERVAL=2;COUNT=8;WKST=SU;BYDAY=TU,TH";
    get_occurrences(_rrule, right_now, 5);
    return 0;
}

Еще несколько проблем:

  • эта строка не делает ничего полезного, но не ясно, чего вы пытаетесь достичь:

    char _size = (char)(((int)'0') + sizeof(result));
    

    все эти броски являются "запахом кода", и это должно сказать вам, что вы делаете что-то очень неправильно здесь

  • ваша функция определяется как возвращающая int, но вы пытаетесь привести ваш массив к time_t и вернуть то, что также не имеет смысла - снова включите предупреждения компилятора - пусть компилятор поможет вам найти и исправить ваши ошибки.

Теперь вы можете использовать это расширение для postgresql.

Пример использования:

SELECT * FROM
     unnest(
         rrule_get_occurrences('FREQ=WEEKLY;INTERVAL=1;WKST=MO;UNTIL=20200101T045102Z;BYDAY=SA;BYHOUR=10;BYMINUTE=51;BYSECOND=2'::rrule,
             '2019-12-07 10:51:02+00'::timestamp with time zone)
     );

          unnest
 ------------------------
  2019-12-07 10:51:02+00
  2019-12-14 10:51:02+00
  2019-12-21 10:51:02+00
  2019-12-28 10:51:02+00
 (4 rows)
Другие вопросы по тегам