Welcome to little lamb

Code » slicd » master » tree

[master] / src / libslicd / slicd_job.c

/*
 * slicd - Copyright (C) 2016 Olivier Brunel
 *
 * slicd_job.c
 * Copyright (C) 2016 Olivier Brunel <jjk@jjacky.com>
 *
 * This file is part of slicd.
 *
 * slicd is free software: you can redistribute it and/or modify it under the
 * terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * slicd is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * slicd. If not, see http://www.gnu.org/licenses/
 */

#include <assert.h>
#include <errno.h>
#include <skalibs/bitarray.h>
#include <slicd/job.h>
#include <slicd/fields.h>
#include <slicd/err.h>


#define ensure_in_range(field,n) \
    if (n < 0 || n > _slicd_fields[field].max)  \
        return -SLICD_ERR_NOT_IN_RANGE

int
slicd_job_has (slicd_job_t    *job,
               slicd_field_t   field,
               int             which)
{
    assert (job != NULL);
    assert (field <= _SLICD_NB_FIELD);

    if (_slicd_fields[field].adjust)
        --which;
    ensure_in_range (field, which);

    return bitarray_isset (job->bits, _slicd_fields[field].offset + which);
}

int
slicd_job_has_days_combo (slicd_job_t    *job)
{
    assert (job != NULL);
    return slicd_job_first (job, SLICD_DAYS_OF_WEEK, 0, 6, 0) <= 6
        /* we're assuming job is valid, i.e. went through
         * slicd_job_ensure_valid() */
        && slicd_job_first (job, SLICD_DAYS, 1, 6, 0) <= 6;
}

slicd_dst_special_t
slicd_job_get_dst_special (slicd_job_t    *job)
{
    slicd_dst_special_t dst = SLICD_DST_OFF;

    assert (job != NULL);

    if (bitarray_peek (job->bits, _SLICD_BITS_DST_SPECIAL))
        dst |= SLICD_DST_ON_DEACTIVATION;
    if (bitarray_peek (job->bits, _SLICD_BITS_DST_SPECIAL + 1))
        dst |= SLICD_DST_ON_ACTIVATION;

    return dst;
}

int
slicd_job_set_dst_special (slicd_job_t        *job,
                           slicd_dst_special_t dst)
{
    assert (job != NULL);
    assert (dst <= SLICD_DST_ON_BOTH);

    bitarray_poke (job->bits, _SLICD_BITS_DST_SPECIAL, dst & SLICD_DST_ON_DEACTIVATION);
    bitarray_poke (job->bits, _SLICD_BITS_DST_SPECIAL + 1, dst & SLICD_DST_ON_ACTIVATION);
    return 0;
}

int
slicd_job_clearset (slicd_job_t    *job,
                    slicd_field_t   field,
                    int             from,
                    int             to,
                    int             what)
{
    assert (job != NULL);
    assert (field <= _SLICD_NB_FIELD);

    if (_slicd_fields[field].adjust)
    {
        --from;
        --to;
    }
    ensure_in_range (field, from);
    ensure_in_range (field, to);
    if (to < from)
        return -SLICD_ERR_INVALID_RANGE;

    bitarray_clearsetn (job->bits, _slicd_fields[field].offset + from, to - from + 1, what);
    return 0;
}

int
slicd_job_swap (slicd_job_t    *job,
                slicd_field_t   field,
                int             from,
                int             to)
{
    assert (job != NULL);
    assert (field <= _SLICD_NB_FIELD);

    if (_slicd_fields[field].adjust)
    {
        --from;
        --to;
    }
    ensure_in_range (field, from);
    ensure_in_range (field, to);
    if (to < from)
        return -SLICD_ERR_INVALID_RANGE;

    bitarray_not (job->bits, _slicd_fields[field].offset + from, to - from + 1);
    return 0;
}

int
slicd_job_first (slicd_job_t    *job,
                 slicd_field_t   field,
                 int             from,
                 int             to,
                 int             what)
{
    int r;

    assert (job != NULL);
    assert (field <= _SLICD_NB_FIELD);

    if (_slicd_fields[field].adjust)
    {
        --from;
        --to;
    }
    ensure_in_range (field, from);
    ensure_in_range (field, to);
    if (to < from)
        return -SLICD_ERR_INVALID_RANGE;

    from += _slicd_fields[field].offset;
    to += _slicd_fields[field].offset;
    if (what)
        r = bitarray_firstset_skip (job->bits, to + 1, from);
    else
        r = bitarray_firstclear_skip (job->bits, to + 1, from);

    return _slicd_fields[field].adjust + r - _slicd_fields[field].offset;
}