r"""Function distribution of combination of chi-squared distributions.

    Parameters
    ----------
    q : float
        Value point at which distribution function is to be evaluated.
    chi2s : ChiSquared
        Chi-squared distributions.
    gcoef : float
        Coefficient of the standard Normal distribution.
    lim : int
        Maximum number of integration terms.
    atol : float
        Absolute error tolerance.
    
    Returns
    -------
    result : float
        Estimated c.d.f. evaluated at ``q``.
    error : int
        0: completed successfully
        1: required accuracy not achieved
        2: round-off error possibly significant
        3: invalid parameters
        4: unable to locate integration parameters
        5: out of memory
    info : Info
        Algorithm information.

def chi2comb_cdf(q, chi2s, gcoef, lim=1000, atol=1e-4):
    r"""Function distribution of combination of chi-squared distributions.

    Parameters
    ----------
    q : float
        Value point at which distribution function is to be evaluated.
    chi2s : ChiSquared
        Chi-squared distributions.
    gcoef : float
        Coefficient of the standard Normal distribution.
    lim : int
        Maximum number of integration terms.
    atol : float
        Absolute error tolerance.
    
    Returns
    -------
    result : float
        Estimated c.d.f. evaluated at ``q``.
    error : int
        0: completed successfully
        1: required accuracy not achieved
        2: round-off error possibly significant
        3: invalid parameters
        4: unable to locate integration parameters
        5: out of memory
    info : Info
        Algorithm information.
    """

    int_type = "i"
    if array(int_type, [0]).itemsize != ffi.sizeof("int"):
        int_type = "l"
        if array(int_type, [0]).itemsize != ffi.sizeof("int"):
            raise RuntimeError("Could not infer a proper integer representation.")

    if array("d", [0.0]).itemsize != ffi.sizeof("double"):
        raise RuntimeError("Could not infer a proper double representation.")

    q = float(q)
    c_chi2s = ffi.new("struct chi2comb_chisquareds *")
    c_info = ffi.new("struct chi2comb_info *")

    ncents = array("d", [float(i.ncent) for i in chi2s])
    coefs = array("d", [float(i.coef) for i in chi2s])
    dofs = array(int_type, [int(i.dof) for i in chi2s])

    c_chi2s.ncents = ffi.cast("double *", ncents.buffer_info()[0])
    c_chi2s.coefs = ffi.cast("double *", coefs.buffer_info()[0])
    c_chi2s.dofs = ffi.cast("int *", dofs.buffer_info()[0])
    c_chi2s.n = len(chi2s)

    result = ffi.new("double *")
    errno = c_chi2comb_cdf(q, c_chi2s, gcoef, lim, atol, c_info, result)

    info = Info()
    methods = ["emag", "niterms", "nints", "intv", "truc", "sd", "ncycles"]
    for i in methods:
        setattr(info, i, getattr(c_info, i))

    return (result[0], errno, info)