Data-Checks

 view release on metacpan or  search on metacpan

src/constraints.c  view on Meta::CPAN


  if(!nargs)
    croak("Require at least one string for StrEq()");

  if(nargs == 1)
    /* We can just store a single string directly */
    c->args[0] = newSVsv_str(args[0]);
  else {
    AV *strs = newAV_alloc_x(nargs);
    for(size_t i = 0; i < nargs; i++)
      av_store(strs, i, newSVsv_str(args[i]));

    c->args[0] = (SV *)strs;
  }

  return ret;
}

static bool constraint_StrMatch(pTHX_ struct Constraint *c, SV *value)
{
  if(!constraint_Str(aTHX_ c, value))
    return false;

  return sv_regexp_match(value, (REGEXP *)c->args[0]);
}

static SV *mk_constraint_StrMatch(pTHX_ SV *arg0)
{
  SV *ret;
  struct Constraint *c;
  alloc_constraint(&ret, &c, &constraint_StrMatch, 1);
  sv_2mortal(ret);

  if(!SvROK(arg0) || !SvRXOK(SvRV(arg0)))
    croak("Require a pre-compiled regexp pattern for StrMatch()");

  c->args[0] = SvREFCNT_inc(SvRV(arg0));

  return ret;
}

static bool constraint_Num(pTHX_ struct Constraint *c, SV *value)
{
  if(!SvOK(value))
    return false;

  if(SvROK(value)) {
    SV *rv = SvRV(value);
    if(!SvOBJECT(rv))
      return false;

    if(sv_has_overload(value, numer_amg))
      return true;

    return false;
  }
  else if(SvPOK(value)) {
    if(!looks_like_number(value))
      return false;

    // reject NaN
    if(SvPVX(value)[0] == 'N' || SvPVX(value)[0] == 'n')
      return false;

    return true;
  }
  else {
    // reject NaN
    if(SvNOK(value) && Perl_isnan(SvNV(value)))
      return false;

    return true;
  }
}

enum {
  NUMBOUND_LOWER_INCLUSIVE = (1<<0),
  NUMBOUND_UPPER_INCLUSIVE = (1<<1),
};

static bool constraint_NumBound(pTHX_ struct Constraint *c, SV *value)
{
  /* First off it must be a Num */
  if(!constraint_Num(aTHX_ c, value))
    return false;

  if(c->args[0]) {
    int cmp = sv_numcmp(c->args[0], value);
    if(cmp > 0 || (cmp == 0 && !(c->flags & NUMBOUND_LOWER_INCLUSIVE)))
      return false;
  }

  if(c->args[1]) {
    int cmp = sv_numcmp(value, c->args[1]);
    if(cmp > 0 || (cmp == 0 && !(c->flags & NUMBOUND_UPPER_INCLUSIVE)))
      return false;
  }

  return true;
}

static SV *mk_constraint_NumGT(pTHX_ SV *arg0)
{
  SV *ret;
  struct Constraint *c;
  alloc_constraint(&ret, &c, &constraint_NumBound, 2);
  sv_2mortal(ret);

  c->args[0] = newSVsv_num(arg0);
  c->args[1] = NULL;

  return ret;
}

static SV *mk_constraint_NumGE(pTHX_ SV *arg0)
{
  SV *ret;
  struct Constraint *c;
  alloc_constraint(&ret, &c, &constraint_NumBound, 2);
  sv_2mortal(ret);

  c->flags   = NUMBOUND_LOWER_INCLUSIVE;
  c->args[0] = newSVsv_num(arg0);
  c->args[1] = NULL;

  return ret;
}



( run in 3.497 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )