{"id":16572079,"url":"https://github.com/eddelbuettel/tidycpp","last_synced_at":"2025-04-13T01:23:46.715Z","repository":{"id":56407317,"uuid":"286588640","full_name":"eddelbuettel/tidycpp","owner":"eddelbuettel","description":"Tidy C++ wrapping of the C API of R","archived":false,"fork":false,"pushed_at":"2024-11-17T23:27:46.000Z","size":127,"stargazers_count":38,"open_issues_count":0,"forks_count":3,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-24T08:02:13.600Z","etag":null,"topics":["cpp","cran","r","r-package"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eddelbuettel.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog","contributing":null,"funding":null,"license":null,"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":"2020-08-10T22:11:30.000Z","updated_at":"2025-03-22T10:48:30.000Z","dependencies_parsed_at":"2024-05-31T00:48:38.949Z","dependency_job_id":"fc3c40eb-37dd-4870-94c7-208a8ff91cbf","html_url":"https://github.com/eddelbuettel/tidycpp","commit_stats":{"total_commits":73,"total_committers":1,"mean_commits":73.0,"dds":0.0,"last_synced_commit":"8a56f8e1712d4be74453b68e42f1a97bca5f6fe9"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eddelbuettel%2Ftidycpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eddelbuettel%2Ftidycpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eddelbuettel%2Ftidycpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eddelbuettel%2Ftidycpp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eddelbuettel","download_url":"https://codeload.github.com/eddelbuettel/tidycpp/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245718776,"owners_count":20661161,"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":["cpp","cran","r","r-package"],"created_at":"2024-10-11T21:26:16.672Z","updated_at":"2025-03-26T19:11:35.544Z","avatar_url":"https://github.com/eddelbuettel.png","language":"C++","readme":"\n## tidyCpp: Tidy C++ wrapping of the C API for R\n\n[![CI](https://github.com/eddelbuettel/tidycpp/workflows/ci/badge.svg)](https://github.com/eddelbuettel/tidycpp/actions?query=workflow%3Aci)\n[![License](https://img.shields.io/badge/license-GPL%20%28%3E=%202%29-brightgreen.svg?style=flat)](https://www.gnu.org/licenses/gpl-2.0.html)\n[![CRAN](https://www.r-pkg.org/badges/version/tidyCpp)](https://cran.r-project.org/package=tidyCpp)\n[![Dependencies](https://tinyverse.netlify.app/badge/tidyCpp)](https://cran.r-project.org/package=tidyCpp)\n[![Downloads](https://cranlogs.r-pkg.org/badges/tidyCpp?color=brightgreen)](https://www.r-pkg.org/pkg/tidyCpp)\n[![Last Commit](https://img.shields.io/github/last-commit/eddelbuettel/tidycpp)](https://github.com/eddelbuettel/tidycpp)\n\n### About\n\nThe C API of the R language and environment is robust, yet a little awkward for C++ programmers.\nThis package wraps a tidy layer of header functions around it.\n\nR Core is moving towards a more explicit classification of which functions are officially part of\nthe API for R, and which ones are 'experimental'.  A [very helpful contributed\npage](https://aitap.codeberg.page/R-api) summarizes the status.\n\n### Examples\n\nA recent motivating example is from the\n[dang](https://github.com/eddelbuettel/dang/blob/master/src/checkNonAscii.cpp) package which\nincludes one unexported Base R function written in C. The original version is\n[here](https://github.com/wch/r-source/blob/trunk/src/library/tools/src/text.c#L140-L184). While\nshort enough, we found working with a _tidier_ version easier and more enjoyable. We include an\nabbreviated version (minus the copyright header) here:\n\n```c++\n#include \u003ctidyCpp\u003e\n\nextern \"C\" {\n\n// cf src/library/tools/src/text.c\nSEXP _check_nonASCII(SEXP text, SEXP ignore_quotes) {\n    /* Check if all the lines in 'text' are ASCII, after removing\n       comments and ignoring the contents of quotes (unless ignore_quotes)\n       (which might span more than one line and might be escaped).\n\n       This cannot be entirely correct, as quotes and \\ might occur as\n       part of another character in a MBCS: but this does not happen\n       in UTF-8.\n    */\n    int i, nbslash = 0; /* number of preceding backslashes */\n    const char *p;\n    char quote= '\\0';\n    Rboolean ign, inquote = FALSE;\n\n    if (!R::isString(text)) R::error(\"invalid input\");\n    ign = (Rboolean) R::asLogical(ignore_quotes);\n    if (ign == NA_LOGICAL) R::error(\"'ignore_quotes' must be TRUE or FALSE\");\n\n    for (i = 0; i \u003c R::length(text); i++) {\n        p = R::charPointer(R::stringElement(text, i)); // ASCII or not not affected by charset\n        inquote = FALSE; /* avoid runaway quotes */\n        for (; *p; p++) {\n            if (!inquote \u0026\u0026 *p == '#') break;\n            if (!inquote || ign) {\n                if ((unsigned int) *p \u003e 127) {\n                    Rprintf(\"%s\\n\", R::charPointer(R::stringElement(text, i)));\n                    Rprintf(\"found %x\\n\", (unsigned int) *p);\n                    return R::scalarLogical(TRUE);\n                }\n            }\n            if ((nbslash % 2 == 0) \u0026\u0026 (*p == '\"' || *p == '\\'')) {\n                if (inquote \u0026\u0026 *p == quote) {\n                    inquote = FALSE;\n                } else if(!inquote) {\n                    quote = *p;\n                    inquote = TRUE;\n                }\n            }\n            if (*p == '\\\\') nbslash++; else nbslash = 0;\n        }\n    }\n    return R::scalarLogical(FALSE);\n}\n\n} // extern \"C\"\n```\n\nAdditions from the `tidyCpp` wrapper can be identified easily via the `R::` namespace. While the\ncode is not hiding its C heritage, we find it overall a little easier to work with. Other examples\n(see below) show how using `tidyCpp` can help avoid the very manual and error-prone `PROTECT` and\n`UNPROTECT` and pairs.\n\nFor additional examples, please see the\n[Motivation](https://cran.r-project.org/package=tidyCpp/vignettes/motivation.html) vignette for a\nlonger discussion with more examples, and the files in the\n[snippets/](https://github.com/eddelbuettel/tidycpp/tree/master/inst/snippets) directory for\ndirectly callable code examples.\n\n### Author\n\nDirk Eddelbuettel\n\n### License\n\nGPL (\u003e= 2)\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feddelbuettel%2Ftidycpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feddelbuettel%2Ftidycpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feddelbuettel%2Ftidycpp/lists"}