def stanc(file=None, charset='utf-8', model_code=None, model_name="anon_model",
          include_paths=None, verbose=False, obfuscate_model_name=True):
    """Translate Stan model specification into C++ code.

    Parameters
    ----------
    file : {string, file}, optional
        If filename, the string passed as an argument is expected to
        be a filename containing the Stan model specification.

        If file, the object passed must have a 'read' method (file-like
        object) that is called to fetch the Stan model specification.

    charset : string, 'utf-8' by default
        If bytes or files are provided, this charset is used to decode.

    model_code : string, optional
        A string containing the Stan model specification. Alternatively,
        the model may be provided with the parameter `file`.

    model_name: string, 'anon_model' by default
        A string naming the model. If none is provided 'anon_model' is
        the default. However, if `file` is a filename, then the filename
        will be used to provide a name.

    include_paths: list of strings, optional
        Paths for #include files defined in Stan code.

    verbose : boolean, False by default
        Indicates whether intermediate output should be piped to the
        console. This output may be useful for debugging.

    obfuscate_model_name : boolean, True by default
        If False the model name in the generated C++ code will not be made
        unique by the insertion of randomly generated characters.
        Generally it is recommended that this parameter be left as True.

    Returns
    -------
    stanc_ret : dict
        A dictionary with the following keys: model_name, model_code,
        cpp_code, and status. Status indicates the success of the translation
        from Stan code into C++ code (success = 0, error = -1).

    Notes
    -----
    C++ reserved words and Stan reserved words may not be used for
    variable names; see the Stan User's Guide for a complete list.
    
    The `#include` method follows a C/C++ syntax `#include foo/my_gp_funs.stan`.
    The method needs to be at the start of the row, no whitespace is allowed.
    After the included file no whitespace or comments are allowed.
    `pystan.experimental`(PyStan 2.18) has a `fix_include`-function to clean the `#include`
    statements from the `model_code`. 
    Example: 
    `from pystan.experimental import fix_include`
    `model_code = fix_include(model_code)`

    See also
    --------
    StanModel : Class representing a compiled Stan model
    stan : Fit a model using Stan

    References
    ----------
    The Stan Development Team (2013) *Stan Modeling Language User's
    Guide and Reference Manual*.  <http://mc-stan.org/>.

    Examples
    --------
    >>> stanmodelcode = '''
    ... data {
    ...   int<lower=0> N;
    ...   real y[N];
    ... }
    ...
    ... parameters {
    ...   real mu;
    ... }
    ...
    ... model {
    ...   mu ~ normal(0, 10);
    ...   y ~ normal(mu, 1);
    ... }
    ... '''
    >>> r = stanc(model_code=stanmodelcode, model_name = "normal1")
    >>> sorted(r.keys())
    ['cppcode', 'model_code', 'model_cppname', 'model_name', 'status']
    >>> r['model_name']
    'normal1'

    """
    if file and model_code:
        raise ValueError("Specify stan model with `file` or `model_code`, "
                         "not both.")
    if file is None and model_code is None:
        raise ValueError("Model file missing and empty model_code.")
    if file is not None:
        if isinstance(file, string_types):
            try:
                with io.open(file, 'rt', encoding=charset) as f:
                    model_code = f.read()
            except:
                logger.critical("Unable to read file specified by `file`.")
                raise
        else:
            model_code = file.read()

    # bytes, going into C++ code
    model_code_bytes = model_code.encode('utf-8')

    if include_paths is None:
        include_paths = [os.path.abspath('.')]
    elif isinstance(include_paths, string_types):
        include_paths = [include_paths]
    # add trailing /
    include_paths = [os.path.join(path, "") for path in include_paths]
    include_paths_bytes = [path.encode('utf-8') for path in include_paths]

    # set to False
    allow_undefined = False

    if obfuscate_model_name:
        # Make the model name depend on the code.
        model_name = (
            model_name + '_' +
            hashlib.md5(model_code_bytes).hexdigest())

    model_name_bytes = model_name.encode('ascii')

    if not isinstance(file, string_types):
        # use default 'unknown file name'
        filename_bytes  = b'unknown file name'
    else:
        # use only the filename, used only for debug printing
        filename_bytes = os.path.split(file)[-1].encode('utf-8')

    result = pystan._api.stanc(model_code_bytes, model_name_bytes,
                               allow_undefined, filename_bytes, 
                               include_paths_bytes,
                              )
    if result['status'] == -1:  # EXCEPTION_RC is -1
        msg = result['msg']
        if PY2:
            # fix problem with unicode in error message in PY2
            msg = msg.encode('ascii', 'replace')
        error_msg = "Failed to parse Stan model '{}'. Error message:\n{}".format(model_name, msg)
        raise ValueError(error_msg)
    elif result['status'] == 0:  # SUCCESS_RC is 0
        logger.debug("Successfully parsed Stan model '{}'.".format(model_name))
    del result['msg']
    result.update({'model_name': model_name})
    result.update({'model_code': model_code})
    result.update({'include_paths' : include_paths})
    return result
Translate Stan model specification into C++ code.

    Parameters
    ----------
    file : {string, file}, optional
        If filename, the string passed as an argument is expected to
        be a filename containing the Stan model specification.

        If file, the object passed must have a 'read' method (file-like
        object) that is called to fetch the Stan model specification.

    charset : string, 'utf-8' by default
        If bytes or files are provided, this charset is used to decode.

    model_code : string, optional
        A string containing the Stan model specification. Alternatively,
        the model may be provided with the parameter `file`.

    model_name: string, 'anon_model' by default
        A string naming the model. If none is provided 'anon_model' is
        the default. However, if `file` is a filename, then the filename
        will be used to provide a name.

    include_paths: list of strings, optional
        Paths for #include files defined in Stan code.

    verbose : boolean, False by default
        Indicates whether intermediate output should be piped to the
        console. This output may be useful for debugging.

    obfuscate_model_name : boolean, True by default
        If False the model name in the generated C++ code will not be made
        unique by the insertion of randomly generated characters.
        Generally it is recommended that this parameter be left as True.

    Returns
    -------
    stanc_ret : dict
        A dictionary with the following keys: model_name, model_code,
        cpp_code, and status. Status indicates the success of the translation
        from Stan code into C++ code (success = 0, error = -1).

    Notes
    -----
    C++ reserved words and Stan reserved words may not be used for
    variable names; see the Stan User's Guide for a complete list.
    
    The `#include` method follows a C/C++ syntax `#include foo/my_gp_funs.stan`.
    The method needs to be at the start of the row, no whitespace is allowed.
    After the included file no whitespace or comments are allowed.
    `pystan.experimental`(PyStan 2.18) has a `fix_include`-function to clean the `#include`
    statements from the `model_code`. 
    Example: 
    `from pystan.experimental import fix_include`
    `model_code = fix_include(model_code)`

    See also
    --------
    StanModel : Class representing a compiled Stan model
    stan : Fit a model using Stan

    References
    ----------
    The Stan Development Team (2013) *Stan Modeling Language User's
    Guide and Reference Manual*.  <http://mc-stan.org/>.

    Examples
    --------
    >>> stanmodelcode = '''
    ... data {
    ...   int<lower=0> N;
    ...   real y[N];
    ... }
    ...
    ... parameters {
    ...   real mu;
    ... }
    ...
    ... model {
    ...   mu ~ normal(0, 10);
    ...   y ~ normal(mu, 1);
    ... }
    ... '''
    >>> r = stanc(model_code=stanmodelcode, model_name = "normal1")
    >>> sorted(r.keys())
    ['cppcode', 'model_code', 'model_cppname', 'model_name', 'status']
    >>> r['model_name']
    'normal1'