{"id":16842603,"url":"https://github.com/rofl0r/tinycpp","last_synced_at":"2026-03-16T11:36:30.438Z","repository":{"id":138311966,"uuid":"196299607","full_name":"rofl0r/tinycpp","owner":"rofl0r","description":"small embeddable C-style preprocessor","archived":false,"fork":false,"pushed_at":"2023-05-12T04:56:00.000Z","size":84,"stargazers_count":39,"open_issues_count":6,"forks_count":10,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-18T08:48:08.928Z","etag":null,"topics":["c","preprocessor"],"latest_commit_sha":null,"homepage":"","language":"C","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/rofl0r.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","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":"2019-07-11T01:40:13.000Z","updated_at":"2025-03-15T16:13:50.000Z","dependencies_parsed_at":null,"dependency_job_id":"567ec15b-c01c-4dc2-8804-391fa8d781f5","html_url":"https://github.com/rofl0r/tinycpp","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rofl0r%2Ftinycpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rofl0r%2Ftinycpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rofl0r%2Ftinycpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rofl0r%2Ftinycpp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rofl0r","download_url":"https://codeload.github.com/rofl0r/tinycpp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244912800,"owners_count":20530764,"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":["c","preprocessor"],"created_at":"2024-10-13T12:47:08.850Z","updated_at":"2026-03-16T11:36:30.405Z","avatar_url":"https://github.com/rofl0r.png","language":"C","readme":"tinycpp - a small, embeddable C-style preprocessor\n==================================================\n\ntinycpp was created with the intention of having a C-style preprocessor\nfor use in an assembler i'm working on.\nthe particular issue i faced with standard C preprocessors is that\nmultiline-macros are expanded into a single line. this basically\nrequires to add something like ';' to the assembler language, to support\nseveral expressions in a single line.\n\none of the design goals from the start was to read the input token by\ntoken, instead of slurping the entire file into memory.\nthis, unfortunately, required some trickery to get the right behaviour\nin some cases, but should save a lot of memory on big files\n(theoretically, it should be able to process gigabyte-big files, while\nonly consuming a few MBs ram (depending on the amount of macros that\nneed to be stored)).\n\napart from that, tinycpp pretty much behaves like your standard cpp.\n\nit's self-hosting: it can preprocess its own source, and the result\ncompiles fine, so it's quite complete (tested with musl libc headers).\n\nsize\n----\nthe 2 TUs used by the preprocessor library are less than 2 KLOC combined.\nadditionally about 500 LOC of list and hash header implementations from\nlibulz are used. this is still a lot less than ucpp's 8 KLOC-ish\nimplementation. not as tiny as i'd like, but a C preprocessor is a\nsurprisingly complex beast.\n\nspeed\n-----\nspeed is slightly slower than GNU cpp, and slightly faster than mcpp on\na 12MB testfile which defines, undefs and uses thousands of macros.\n\ndifferences to standard C preprocessors\n---------------------------------------\n\n- \"if\" evaluation treats all numeric literals as integers, even if they\n  have L/U/LL/LLU suffixes. this is probably the biggest blocker from\n  becoming a fully compliant C preprocessor.\n  shouldn't be hard to support though.\n- widechar literals in conditionals are treated as if they were a single\n  non-wide character.\n- multiline macros keep newline characters, which doesn't cause any\n  issues, apart from making it harder to diff against other CPPs output.\n  (`__LINE__` macro behaves as expected, though, in that it shows the same\n  line number for all expanded lines).\n- no predefined macros such as `__STDC__`. you can set them yourself, if\n  you like.\n- a few test cases of mcpp fail. these are cornercases that are usually\n  not encountered in the wild.\n  e.g. https://github.com/ned14/mcpp/blob/master/test-c/n_5.c\n- lines starting w/ comments like `/**/` followed by preprocessor directives\n  are currently not detected as such. this is because comments are removed\n  on the fly, not in a previous pass. it shouldn't be very hard to support\n  it, though.\n- no digraphs and trigraphs supported.\n- multiple sequential whitespace characters are preserved.\n- max token length is 4095, though this can easily be changed.\n  many CPPs happily process much longer tokens, even though the standard\n  doesn't require it.\n- some built-ins like `__TIME__` and `__DATE__` are missing, but you can\n  define them yourself if needed. `__LINE__` and `__FILE_`_ were added,\n  as they're used by musl's headers.\n- the printed diagnostics are sometimes not very helpful.\n\nanything else not mentioned here is supported (including varargs, pasting,\nstringification, ...)\n\ndifferences to other C preprocessor libraries\n---------------------------------------------\n\nthe preprocessor interface takes a `FILE*` as input and one as output.\nit doesn't try to provide a C token stream.\nin order not to write to disk, you can use memory streams\n(open_memstream() to create a writable stream, followed by fflush() to\nmake its contents available)\n\nhow to build\n------------\nclone the libulz library https://github.com/rofl0r/libulz, and point the\nMakefile to the directory, or copy the 3 headers needed into the source\ntree, then run `make`.\n\nhow to use\n----------\nlook at `preproc.h` and `cppmain.c`, which implements the demo preprocessor\nprogram.\n\nacknowledgements\n----------------\nthanks go to mcpp's author, whose testsuite i extensively used.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frofl0r%2Ftinycpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frofl0r%2Ftinycpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frofl0r%2Ftinycpp/lists"}