{"id":15010888,"url":"https://github.com/haskell/hsc2hs","last_synced_at":"2025-04-07T13:07:47.329Z","repository":{"id":26255250,"uuid":"107773130","full_name":"haskell/hsc2hs","owner":"haskell","description":"Pre-processor for .hsc files","archived":false,"fork":false,"pushed_at":"2025-03-17T14:10:53.000Z","size":343,"stargazers_count":40,"open_issues_count":20,"forks_count":28,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-03-29T02:41:59.330Z","etag":null,"topics":["ffi","haskell","preprocessor"],"latest_commit_sha":null,"homepage":"http://hackage.haskell.org/package/hsc2hs","language":"Haskell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/haskell.png","metadata":{"files":{"readme":"README.rst","changelog":"changelog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-10-21T11:01:22.000Z","updated_at":"2025-03-17T14:10:57.000Z","dependencies_parsed_at":"2023-01-14T04:17:22.096Z","dependency_job_id":"328b29f6-dbc8-40ca-8ae2-80127fc23013","html_url":"https://github.com/haskell/hsc2hs","commit_stats":{"total_commits":360,"total_committers":42,"mean_commits":8.571428571428571,"dds":0.6972222222222222,"last_synced_commit":"2d6e7a3385526410146e2817fcba3de88b5fc6a8"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haskell%2Fhsc2hs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haskell%2Fhsc2hs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haskell%2Fhsc2hs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/haskell%2Fhsc2hs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/haskell","download_url":"https://codeload.github.com/haskell/hsc2hs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247419858,"owners_count":20936012,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ffi","haskell","preprocessor"],"created_at":"2024-09-24T19:37:01.935Z","updated_at":"2025-04-07T13:07:47.309Z","avatar_url":"https://github.com/haskell.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"``hsc2hs``: Haskell Pre-processor for C FFI bindings\n####################################################\n|Hackage| |Linux build| |Windows build|\n\nThe ``hsc2hs`` command can be used to automate some parts of the process\nof writing Haskell bindings to C code. It reads an almost-Haskell source\nwith embedded special constructs, and outputs a real Haskell file with\nthese constructs processed, based on information taken from some C\nheaders. The extra constructs deal with accessing C data from Haskell.\n\nIt may also output a C file which contains additional C functions to be\nlinked into the program, together with a C header that gets included\ninto the C code to which the Haskell module will be compiled (when\ncompiled via C) and into the C file. These two files are created when\nthe ``#def`` construct is used (see below).\n\nActually ``hsc2hs`` does not output the Haskell file directly. It\ncreates a C program that includes the headers, gets automatically\ncompiled and run. That program outputs the Haskell code.\n\nIn the following, \"Haskell file\" is the main output (usually a ``.hs``\nfile), \"compiled Haskell file\" is the Haskell file after ``ghc`` has\ncompiled it to C (i.e. a ``.hc`` file), \"C program\" is the program that\noutputs the Haskell file, \"C file\" is the optionally generated C file,\nand \"C header\" is its header file.\n\n.. contents::\n\nCommand line syntax\n~~~~~~~~~~~~~~~~~~~\n\n``hsc2hs`` takes input files as arguments, and flags that modify its\nbehavior:\n\n``-o FILE``, ``--output=FILE``\n    Name of the Haskell file.\n\n``-t FILE``, ``--template=FILE``\n    The template file (see below).\n\n``-c PROG``, ``--cc=PROG``\n    The C compiler to use (default: ``gcc``)\n\n``-l PROG``, ``--ld=PROG``\n    The linker to use (default: ``gcc``).\n\n``-C FLAG``, ``--cflag=FLAG``\n    An extra flag to pass to the C compiler.\n\n``-I DIR``\n    Passed to the C compiler.\n\n``-L FLAG``, ``--lflag=FLAG``\n    An extra flag to pass to the linker.\n\n``-i FILE``, ``--include=FILE``\n    As if the appropriate ``#include`` directive was placed in the\n    source.\n\n``-D NAME[=VALUE]``, ``--define=NAME[=VALUE]``\n    As if the appropriate ``#define`` directive was placed in the\n    source.\n\n``--no-compile``\n    Stop after writing out the intermediate C program to disk. The file\n    name for the intermediate C program is the input file name with\n    ``.hsc`` replaced with ``_hsc_make.c``.\n\n``-k``, ``--keep-files``\n    Proceed as normal, but do not delete any intermediate files.\n\n``-x``, ``--cross-compile``\n    Activate cross-compilation mode (see `cross-compilation`_).\n\n``--cross-safe``\n    Restrict the .hsc directives to those supported by the\n    ``--cross-compile`` mode (see `cross-compilation`_). This should be\n    useful if your ``.hsc`` files must be safely cross-compiled and you\n    wish to keep non-cross-compilable constructs from creeping into\n    them.\n\n``-?``, ``--help``\n    Display a summary of the available flags and exit successfully.\n\n``-V``, ``--version``\n    Output version information and exit successfully.\n\nThe input file should end with .hsc (it should be plain Haskell source\nonly; literate Haskell is not supported at the moment). Output files by\ndefault get names with the ``.hsc`` suffix replaced:\n\n+--------------+----------------+\n| ``.hs``      | Haskell file   |\n+--------------+----------------+\n| ``_hsc.h``   | C header       |\n+--------------+----------------+\n| ``_hsc.c``   | C file         |\n+--------------+----------------+\n\nThe C program is compiled using the Haskell compiler. This provides the\ninclude path to ``HsFFI.h`` which is automatically included into the C\nprogram.\n\nInput syntax\n~~~~~~~~~~~~\n\nAll special processing is triggered by the ``#`` operator. To output a\nliteral ``#``, write it twice: ``##``. Inside string literals and\ncomments ``#`` characters are not processed.\n\nA ``#`` is followed by optional spaces and tabs, an alphanumeric keyword\nthat describes the kind of processing, and its arguments. Arguments look\nlike C expressions separated by commas (they are not written inside\nparens). They extend up to the nearest unmatched ``)``, ``]`` or ``}``,\nor to the end of line if it occurs outside any ``() [] {} '' \"\" /**/``\nand is not preceded by a backslash. Backslash-newline pairs are\nstripped.\n\nIn addition ``#{stuff}`` is equivalent to ``#stuff`` except that it's\nself-delimited and thus needs not to be placed at the end of line or in\nsome brackets.\n\nMeanings of specific keywords:\n\n``#include \u003cfile.h\u003e``, ``#include \"file.h\"``\n    The specified file gets included into the C program, the compiled\n    Haskell file, and the C header. ``\u003cHsFFI.h\u003e`` is included\n    automatically.\n\n``#define ⟨name⟩``, ``#define ⟨name ⟨value⟩``, ``#undef ⟨name⟩``\n    Similar to ``#include``. Note that ``#includes`` and ``#defines``\n    may be put in the same file twice so they should not assume\n    otherwise.\n\n``#let ⟨name⟩ ⟨parameters⟩ = \"⟨definition⟩\"``\n    Defines a macro to be applied to the Haskell source. Parameter names\n    are comma-separated, not inside parens. Such macro is invoked as\n    other ``#``-constructs, starting with ``#name``. The definition will\n    be put in the C program inside parens as arguments of ``printf``. To\n    refer to a parameter, close the quote, put a parameter name and open\n    the quote again, to let C string literals concatenate. Or use\n    ``printf``'s format directives. Values of arguments must be given as\n    strings, unless the macro stringifies them itself using the C\n    preprocessor's ``#parameter`` syntax.\n\n``#def ⟨C_definition⟩``\n    The definition (of a function, variable, struct or typedef) is\n    written to the C file, and its prototype or extern declaration to\n    the C header. Inline functions are handled correctly. struct\n    definitions and typedefs are written to the C program too. The\n    ``inline``, ``struct`` or ``typedef`` keyword must come just after\n    ``def``.\n\n``#if ⟨condition⟩``, ``#ifdef ⟨name⟩``, ``#ifndef ⟨name⟩``, ``#elif ⟨condition⟩``, ``#else``, ``#endif``, ``#error ⟨message⟩``, ``#warning ⟨message⟩``\n    Conditional compilation directives are passed unmodified to the C\n    program, C file, and C header. Putting them in the C program means\n    that appropriate parts of the Haskell file will be skipped.\n\n``#const ⟨C_expression⟩``\n    The expression must be convertible to ``long`` or ``unsigned long``.\n    Its value (literal or negated literal) will be output.\n\n``#const_str ⟨C_expression⟩``\n    The expression must be convertible to const char pointer. Its value\n    (string literal) will be output.\n\n``#type ⟨C_type⟩``\n    A Haskell equivalent of the C numeric type will be output. It will\n    be one of ``{Int,Word}{8,16,32,64}``, ``Float``, ``Double``,\n    ``LDouble``.\n\n``#peek ⟨struct_type⟩, ⟨field⟩``\n    A function that peeks a field of a C struct will be output. It will\n    have the type ``Storable b =\u003e Ptr a -\u003e IO b``. The intention is that\n    ``#peek`` and ``#poke`` can be used for implementing the operations\n    of class ``Storable`` for a given C struct (see the\n    ``Foreign.Storable`` module in the library documentation).\n\n``#poke ⟨struct_type⟩, ⟨field⟩``\n    Similarly for poke. It will have the type\n    ``Storable b =\u003e Ptr a -\u003e b -\u003e IO ()``.\n\n``#ptr ⟨struct_type⟩, ⟨field⟩``\n    Makes a pointer to a field struct. It will have the type\n    ``Ptr a -\u003e Ptr b``.\n\n``#offset ⟨struct_type⟩, ⟨field⟩``\n    Computes the offset, in bytes, of ``field`` in ``struct_type``. It\n    will have type ``Int``.\n\n``#size ⟨struct_type⟩``\n    Computes the size, in bytes, of ``struct_type``. It will have type\n    ``Int``.\n\n``#alignment ⟨struct_type⟩``\n    Computes the alignment, in bytes, of ``struct_type``. It will have type\n    ``Int``.\n\n``#enum ⟨type⟩, ⟨constructor⟩, ⟨value⟩, ⟨value⟩, ...``\n    A shortcut for multiple definitions which use ``#const``. Each\n    ``value`` is a name of a C integer constant, e.g. enumeration value.\n    The name will be translated to Haskell by making each letter\n    following an underscore uppercase, making all the rest lowercase,\n    and removing underscores. You can supply a different translation by\n    writing ``hs_name = c_value`` instead of a ``value``, in which case\n    ``c_value`` may be an arbitrary expression. The ``hs_name`` will be\n    defined as having the specified ``type``. Its definition is the\n    specified ``constructor`` (which in fact may be an expression or be\n    empty) applied to the appropriate integer value. You can have\n    multiple ``#enum`` definitions with the same ``type``; this\n    construct does not emit the type definition itself.\n\nCustom constructs\n~~~~~~~~~~~~~~~~~\n\n``#const``, ``#type``, ``#peek``, ``#poke`` and ``#ptr`` are not\nhardwired into the ``hsc2hs``, but are defined in a C template that is\nincluded in the C program: ``template-hsc.h``. Custom constructs and\ntemplates can be used too. Any ``#``\\-construct with unknown key is\nexpected to be handled by a C template.\n\nA C template should define a macro or function with name prefixed by\n``hsc_`` that handles the construct by emitting the expansion to stdout.\nSee ``template-hsc.h`` for examples.\n\nSuch macros can also be defined directly in the source. They are useful\nfor making a ``#let``\\-like macro whose expansion uses other ``#let``\nmacros. Plain ``#let`` prepends ``hsc_`` to the macro name and wraps the\ndefinition in a ``printf`` call.\n\n.. _cross-compilation:\n\nCross-compilation\n~~~~~~~~~~~~~~~~~\n\n``hsc2hs`` normally operates by creating, compiling, and running a C\nprogram. That approach doesn't work when cross-compiling — in this\ncase, the C compiler's generates code for the target machine, not the\nhost machine. For this situation, there's a special mode\n``hsc2hs --cross-compile`` which can generate the .hs by extracting\ninformation from compilations only — specifically, whether or not\ncompilation fails.\n\nOnly a subset of ``.hsc`` syntax is supported by ``--cross-compile``.\nThe following are unsupported:\n\n-  ``#{const_str}``\n-  ``#{let}``\n-  ``#{def}``\n-  Custom constructs\n\n.. |Hackage| image:: https://img.shields.io/hackage/v/hsc2hs.svg\n    :target: http://hackage.haskell.org/package/hsc2hs\n.. |Linux build| image:: https://github.com/haskell/hsc2hs/actions/workflows/haskell-ci.yml/badge.svg\n    :target: https://github.com/haskell/hsc2hs/actions/workflows/haskell-ci.yml\n.. |Windows build| image:: https://ci.appveyor.com/api/projects/status/ee434vcpvit2qeqh?svg=true\n    :target: https://ci.appveyor.com/project/RyanGlScott/hsc2hs\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaskell%2Fhsc2hs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhaskell%2Fhsc2hs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhaskell%2Fhsc2hs/lists"}