<commit_before>import lazy_rest, external/badger_bits/bb_system, strtabs

## Exported C API of `lazy_rest <https://github.com/gradha/lazy_rest>`_ a
## reStructuredText processing module for Nimrod.
##
## These are simple Nimrod wrappers around the main `lazy_rest.nim
## <lazy_rest.html>`_ module. They just document and export for C the most
## interesting procs to be consumed by other C programs. Usually you will
## compile this module using the `--header command line switch
## <http://nimrod-lang.org/backends.html#backend-code-calling-nimrod>`_ which
## generates the appropriate ``.c`` and ``.h`` files inside the `nimcache
## directory <http://nimrod-lang.org/backends.html#nimcache-naming-logic>`_,
## then compile those into your C program.
##
## Due to the differences between Nimrod and C, most of the wrapper procs will
## assign the return values to Nimrod global variables so that their memory is
## not freed while *other* Nimrod code executes (potentially triggering garbage
## collections). This means the C API is not thread safe nor reentrant.  You
## should also always call these procs from the main thread UI due to the
## garbage collector not being thread aware either.
##
## When passing ``cstring`` types back and forth, consider all of them to be
## ``char*`` strings encoded in UTF8. This means that you are not able to pass
## embedded ``NULLs`` in text since they will be treated as string terminators.
## In practice this should not be a problem given the nature of text
## processing.


type
  C_state = object
    error_rst_file_to_html: ref E_Base
    error_rst_string_to_html: ref E_Base
    errors_safe_rst_file_to_html: seq[string]
    errors_safe_rst_string_to_html: seq[string]
    ret_nim_file_to_html: string
    ret_parse_rst_options: PStringTable
    ret_rst_file_to_html: string
    ret_rst_string_to_html: string
    ret_safe_rst_file_to_html: string
    ret_safe_rst_string_to_html: string
    ret_set_normal_error_rst: seq[string]
    ret_set_safe_error_rst: seq[string]


var C: C_state


proc lr_version_int*(major, minor, maintenance: ptr cint)
    {.exportc, cdecl, raises: [].} =
  ## Wraps `version_int <lazy_rest.html#version_int>`_ for C.
  ##
  ## Pass pointers to whatever version values you are interested it and they
  ## will be filled. Example:
  ##
  ## .. code-block:: c
  ##    int major = 6, minor = 6, maintenance = 6;
  ##    lr_version_int(&major, &minor, &maintenance);
  ##    printf("Using lazy_rest: %d-%d-%d.\n",
  ##       major, minor, maintenance);
  ##    // --> Using lazy_rest: 0-1-0.
  if major.not_nil: major[] = version_int.major.cint
  if minor.not_nil: minor[] = version_int.minor.cint
  if maintenance.not_nil: maintenance[] = version_int.maintenance.cint


proc lr_version_str*(): cstring {.exportc, raises: [].} =
  ## Wraps `version_str <lazy_rest.html#version_str>`_ for C.
  ##
  ## Always returns the same pointer to a valid ``cstring``. Example:
  ##
  ## .. code-block:: c
  ##    printf("Using lazy_rest %s.\n", lr_version_str());
  ##    // --> Using lazy_rest 0.1.0.
  result = version_str.cstring


proc lr_parse_rst_options*(options: cstring): PStringTable
    {.exportc, raises: [].} =
  ## Wraps `parse_rst_options() <lazy_rest.html#parse_rst_options>`_ for C.
  ##
  ## The return value is stored in a global variable so future calls to this
  ## function will mangle the returned value. It is unlikely you will need to
  ## call this more than once though.
  ##
  ## Also, due to a `limitation <https://github.com/Araq/Nimrod/issues/1579>`_
  ## in Nimrod's exportc pragma, right now the ``PStringTable`` type will be
  ## exported to the C header like ``typedef struct tstringtable128812
  ## tstringtable128812``, so it may be difficult or impossible to write
  ## crossplatform source code which calls this function, given that each
  ## platform's Nimrod compiler (or version) may generate a different symbol.
  ## Still, the function is here for completeness (and maybe you don't mind the
  ## weird ``typedef``).
  C.ret_parse_rst_options = parse_rst_options(options.nil_string)
  result = C.ret_parse_rst_options


proc lr_rst_string_to_html*(content, filename: cstring,
    config: PStringTable): cstring {.exportc, raises: [].} =
  ## Wraps `rst_string_to_html() <lazy_rest.html#rst_string_to_html>`_ for C.
  ##
  ## Returns a ``cstring`` with HTML or a ``null`` pointer if there were
  ## errors.  In case of errors you can call `lr_rst_string_to_html_error()
  ## <#lr_rst_string_to_html_error>`_ to retrieve the description, which will
  ## be the text of the Nimrod exception.
  ##
  ## The memory of the returned ``cstring`` will be kept until the next call to
  ## this function, you may need to copy it somewhere. Example:
  ##
  ## .. code-block:: c
  ##    char *s = lr_rst_string_to_html(valid_rst_string,
  ##       "<string>", 0);
  ##    if (s) {
  ##       // Success!
  ##    } else {
  ##       // Handle error.
  ##    }
  let
    filename = filename.nil_string
    content = content.nil_string
  C.ret_rst_string_to_html = nil<commit_msg>Adds lr_set_global_rst_options() workaround. Refs #12.<commit_after>import lazy_rest, external/badger_bits/bb_system, strtabs

## Exported C API of `lazy_rest <https://github.com/gradha/lazy_rest>`_ a
## reStructuredText processing module for Nimrod.
##
## These are simple Nimrod wrappers around the main `lazy_rest.nim
## <lazy_rest.html>`_ module. They just document and export for C the most
## interesting procs to be consumed by other C programs. Usually you will
## compile this module using the `--header command line switch
## <http://nimrod-lang.org/backends.html#backend-code-calling-nimrod>`_ which
## generates the appropriate ``.c`` and ``.h`` files inside the `nimcache
## directory <http://nimrod-lang.org/backends.html#nimcache-naming-logic>`_,
## then compile those into your C program.
##
## Due to the differences between Nimrod and C, most of the wrapper procs will
## assign the return values to Nimrod global variables so that their memory is
## not freed while *other* Nimrod code executes (potentially triggering garbage
## collections). This means the C API is not thread safe nor reentrant.  You
## should also always call these procs from the main thread UI due to the
## garbage collector not being thread aware either.
##
## When passing ``cstring`` types back and forth, consider all of them to be
## ``char*`` strings encoded in UTF8. This means that you are not able to pass
## embedded ``NULLs`` in text since they will be treated as string terminators.
## In practice this should not be a problem given the nature of text
## processing.
##
## There is a limitation with regards to passing configuration options from C
## (see `lr_parse_rst_options() <#lr_parse_rst_options>`_) so the convenience
## `lr_set_global_rst_options() <#lr_set_global_rst_options>`_ is provided
## instead. The public API will remain having configuration options as
## parameters for the future though.


type
  C_state = object
    error_rst_file_to_html: ref E_Base
    error_rst_string_to_html: ref E_Base
    errors_safe_rst_file_to_html: seq[string]
    errors_safe_rst_string_to_html: seq[string]
    ret_nim_file_to_html: string
    ret_parse_rst_options: PStringTable
    ret_rst_file_to_html: string
    ret_rst_string_to_html: string
    ret_safe_rst_file_to_html: string
    ret_safe_rst_string_to_html: string
    ret_set_normal_error_rst: seq[string]
    ret_set_safe_error_rst: seq[string]
    global_options: PStringTable


var C: C_state


proc lr_version_int*(major, minor, maintenance: ptr cint)
    {.exportc, cdecl, raises: [].} =
  ## Wraps `version_int <lazy_rest.html#version_int>`_ for C.
  ##
  ## Pass pointers to whatever version values you are interested it and they
  ## will be filled. Example:
  ##
  ## .. code-block:: c
  ##    int major = 6, minor = 6, maintenance = 6;
  ##    lr_version_int(&major, &minor, &maintenance);
  ##    printf("Using lazy_rest: %d-%d-%d.\n",
  ##       major, minor, maintenance);
  ##    // --> Using lazy_rest: 0-1-0.
  if major.not_nil: major[] = version_int.major.cint
  if minor.not_nil: minor[] = version_int.minor.cint
  if maintenance.not_nil: maintenance[] = version_int.maintenance.cint


proc lr_version_str*(): cstring {.exportc, raises: [].} =
  ## Wraps `version_str <lazy_rest.html#version_str>`_ for C.
  ##
  ## Always returns the same pointer to a valid ``cstring``. Example:
  ##
  ## .. code-block:: c
  ##    printf("Using lazy_rest %s.\n", lr_version_str());
  ##    // --> Using lazy_rest 0.1.0.
  result = version_str.cstring


proc lr_parse_rst_options*(options: cstring): PStringTable
    {.exportc, raises: [].} =
  ## Wraps `parse_rst_options() <lazy_rest.html#parse_rst_options>`_ for C.
  ##
  ## The return value is stored in a global variable so future calls to this
  ## function will mangle the returned value. It is unlikely you will need to
  ## call this more than once though.
  ##
  ## Also, due to a `limitation <https://github.com/Araq/Nimrod/issues/1579>`_
  ## in Nimrod's exportc pragma, right now the ``PStringTable`` type will be
  ## exported to the C header like ``typedef struct tstringtable128812
  ## tstringtable128812``, so it may be difficult or impossible to write
  ## crossplatform source code which calls this function, given that each
  ## platform's Nimrod compiler (or version) may generate a different symbol.
  ## Still, the function is here for completeness (and maybe you don't mind the
  ## weird ``typedef``). You can use `lr_set_global_rst_options()
  ## <#lr_set_global_rst_options>`_ to work around this issue.
  C.ret_parse_rst_options = parse_rst_options(options.nil_string)
  result = C.ret_parse_rst_options


proc lr_set_global_rst_options*(options: cstring): cint
    {.discardable, exportc, raises: [].} =
  ## Works around `lr_parse_rst_options() <#lr_parse_rst_options>`_ limitations.
  ##
  ## Since in C you can't get a hold of the type of a ``PStringTable``
  ## conveniently, this will call `lr_parse_rst_options()
  ## <#lr_parse_rst_options>`_ and store the result in a special global
  ## variable. From this moment on, every call to the public API which accepts
  ## a ``PStringTable``, if you pass ``null`` the global variable stored by
  ## this function will be used instead.
  ##
  ## At some point in the future this function will disappear (obviously when
  ## ``PStringTable`` can be exported properly).
  ##
  ## Returns zero if `lr_parse_rst_options() <#lr_parse_rst_options>`_ returned
  ## ``nil``, non zero otherwise.
  C.global_options = options.lr_parse_rst_options
  result = if C.global_options.is_nil: 0 else: 1


proc lr_rst_string_to_html*(content, filename: cstring,
    config: PStringTable): cstring {.exportc, raises: [].} =
  ## Wraps `rst_string_to_html() <lazy_rest.html#rst_string_to_html>`_ for C.
  ##
  ## Returns a ``cstring`` with HTML or a ``null`` pointer if there were
  ## errors.  In case of errors you can call `lr_rst_string_to_html_error()
  ## <#lr_rst_string_to_html_error>`_ to retrieve the description, which will
  ## be the text of the Nimrod exception.
  ##
  ## The memory of the returned ``cstring`` will be kept until the next call to
  ## this function, you may need to copy it somewhere. Example:
  ##
  ## .. code-block:: c
  ##    char *s = lr_rst_string_to_html(valid_rst_string,
  ##       "<string>", 0);
  ##    if (s) {
  ##       // Success!
  ##    } else {
  ##       // Handle error.
  ##    }
  let
    filename = filename.nil_string
    content = content.nil_string
  C.ret_rst_string_to_html = nil
{'fraction_non_alphanumeric': 0.10971191995859927, 'fraction_numerical': 0.005002587545282043, 'mean_word_length': 4.054489973844812, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 35, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5174151', 'n_tokens_mistral': 3853, 'n_tokens_neox': 3669, 'n_words': 1237}