{"action":"created","issue":{"url":"https://api.github.com/repos/jgm/cmark/issues/119","repository_url":"https://api.github.com/repos/jgm/cmark","labels_url":"https://api.github.com/repos/jgm/cmark/issues/119/labels{/name}","comments_url":"https://api.github.com/repos/jgm/cmark/issues/119/comments","events_url":"https://api.github.com/repos/jgm/cmark/issues/119/events","html_url":"https://github.com/jgm/cmark/issues/119","id":143844105,"number":119,"title":"Consider usage of the GLib in libcmark","user":{"login":"MathieuDuponchelle","id":1278273,"avatar_url":"https://avatars.githubusercontent.com/u/1278273?v=3","gravatar_id":"","url":"https://api.github.com/users/MathieuDuponchelle","html_url":"https://github.com/MathieuDuponchelle","followers_url":"https://api.github.com/users/MathieuDuponchelle/followers","following_url":"https://api.github.com/users/MathieuDuponchelle/following{/other_user}","gists_url":"https://api.github.com/users/MathieuDuponchelle/gists{/gist_id}","starred_url":"https://api.github.com/users/MathieuDuponchelle/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/MathieuDuponchelle/subscriptions","organizations_url":"https://api.github.com/users/MathieuDuponchelle/orgs","repos_url":"https://api.github.com/users/MathieuDuponchelle/repos","events_url":"https://api.github.com/users/MathieuDuponchelle/events{/privacy}","received_events_url":"https://api.github.com/users/MathieuDuponchelle/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":24,"created_at":"2016-03-27T20:09:04Z","updated_at":"2016-04-16T18:13:46Z","closed_at":null,"body":"This subject has been briefly discussed in #100 , but I figured a separate issue to sum up arguments for and against that, and discuss whether this would be acceptable would be useful.\r\n\r\n### Argument(s) against using the glib\r\n\r\nThe main (and only) argument raised against using the glib is that of portability. I would argue its usage would actually help with portability, with respect to things like loading of plugins, or threading.\r\n\r\nNote that I will open  another issue at some point regarding multithreading of the inline parsing phase, as I think this phase is very amenable to parallelization, as long as the separation of inline and block parsing is consistently enforced.\r\n\r\nI'm working for an Open Source software consultancy company, [collabora](https://www.collabora.com/), where we routinely deploy glib-based solutions on a wide range of architectures and operating systems, including Windows, and I've never seen any issues with glib's portability.\r\n\r\nI'm writing this from my seldom-used Windows partition, where I've just successfully compiled a version of cmark built against the glib, thanks to the [MSYS2](https://msys2.github.io/) project this has been a completely painless experience. Note that it is also trivial to provide installers using that solution.\r\n\r\n### Arguments for using the glib\r\n\r\n#### Features\r\n\r\nSee https://developer.gnome.org/glib/2.48/ for the full list of features, here are a few I think are relevant for cmark, in that they could make its codebase way leaner, and help implement features in a portable manner.\r\n\r\n* [Portable basic types](https://developer.gnome.org/glib/2.48/glib-Basic-Types.html): gboolean would for example help get us rid of [that code](https://github.com/jgm/cmark/blob/master/src/config.h.in#L8), by the way I'm not even sure how cmark could compile at all when the preprocessor enters the #elif !defined(__cplusplus) preproc branch there, as true and false will not be defined.\r\n\r\n* [Standard high-level data structures](https://developer.gnome.org/glib/2.48/glib-data-types.html): Having to implement a poor man's linked list in my work on extensions isn't something I'm satisfied with, more generally the more wheels one reinvents the more surface for bugs one has to maintain. I think (not sure) that reference maps are implemented as a hashtable, one could use a GHashTable for this instead. The AST could be implemented as an N-ary tree etc.\r\n\r\n* String-related utilities: https://developer.gnome.org/glib/2.48/glib-String-Chunks.html https://developer.gnome.org/glib/2.48/glib-Strings.html and https://developer.gnome.org/glib/2.48/glib-String-Utility-Functions.html would let us get rid of cmark_chunk and cmark_strbuf, which I had to expose in the API for extensions.\r\n\r\n* [Unicode handling](https://developer.gnome.org/glib/2.48/glib-Unicode-Manipulation.html): I think the plethora of functions defined in there would make most if not all of the utf8 handling code in cmark irrelevant.\r\n\r\n* Error handling / Logging: https://developer.gnome.org/glib/2.48/glib-Warnings-and-Assertions.html, https://developer.gnome.org/glib/2.48/glib-Message-Logging.html and https://developer.gnome.org/glib/2.48/glib-Error-Reporting.html would be more than useful to improve ease of debugging of the library for us developers, as well as offer a more advanced error API.\r\n\r\n* Parsing and lexing utilities: https://developer.gnome.org/glib/2.48/glib-Lexical-Scanner.html,https://developer.gnome.org/glib/2.48/glib-regex-syntax.html : I haven't benchmarked these functions, but I'm pretty sure re2c - generated scanners will blow them out of the water performance-wise, however their performance might be adequate for extension implementers who would desire a higher-level lexing / regex interface, and would directly have one available when linking with libcmark.\r\n\r\n* Filesystem-related utilities: https://developer.gnome.org/glib/2.48/glib-File-Utilities.html and https://developer.gnome.org/glib/2.48/glib-URI-Functions.html contain functions that would help simplify some code paths as well.\r\n\r\n* [command-line parser](https://developer.gnome.org/glib/2.48/glib-Commandline-option-parser.html) to get rid of and improve the equivalent code in the cmark executable.\r\n\r\n* [Testing](https://developer.gnome.org/glib/2.48/glib-Testing.html): this wouldn't hurt either :)\r\n\r\n* [GApplication](https://developer.gnome.org/gio/stable/GApplication.html): not really needed for now, but one could imagine this being useful if we ever wanted to have a \"cmark server\".\r\n\r\n* Threading: https://developer.gnome.org/glib/2.48/glib-Thread-Pools.html would help a lot in portably parallelizing inline parsing. I haven't benchmarked this, but I believe there's a significant performance reserve to tap into in that direction, which could be very valuable for one of cmark's announced use cases, which is to be run server-side.\r\n\r\n* [Plugin loading](https://developer.gnome.org/glib/2.48/glib-Dynamic-Loading-of-Modules.html): would be extremely useful for extensions obviously.\r\n\r\n#### Other arguments\r\n\r\n* cmark is already a moderately complex library, which implements internally things that have been standard in the glib for ages. My work on extensions only complexifies it a bit more, with the addition of (linux-only) plugin-loading code, a linked list, exposing API that has nothing to do with cmark's actual job ... Using the glib would drastically reduce the scope of the library, and actually help improve its behaviour and portability. I think this outweighs by far the distribution concerns, which simply need to be addressed once and for all by updating the installing documentation, and possibly providing helpers such as Visual Studio solutions for people insisting on using that piece of technology (I'm afraid I won't be able to help there).\r\n\r\n* The \"glib port\" is by no means something that needs to happen all at once, it can be done incrementally, and wouldn't interfere with daily development.\r\n\r\n* We could decide at some point to port some of the already kind of object-oriented API to GObject, which would let us offer dynamic introspection capabilities for javascript and python\r\n\r\n* I really really think this is a good idea, if that's any help :)\r\n\r\n@nwellnhof , I know you're concerned with this, but please come to this with an open mind, consider all the things the glib would bring to the table, and evaluate whether this port would *really* prevent you from using cmark at all, or simply mean spending ten minutes figuring out how to update your bundling of cmark, which could profit to other people using that practice."},"comment":{"url":"https://api.github.com/repos/jgm/cmark/issues/comments/210867768","html_url":"https://github.com/jgm/cmark/issues/119#issuecomment-210867768","issue_url":"https://api.github.com/repos/jgm/cmark/issues/119","id":210867768,"user":{"login":"gjtorikian","id":64050,"avatar_url":"https://avatars.githubusercontent.com/u/64050?v=3","gravatar_id":"","url":"https://api.github.com/users/gjtorikian","html_url":"https://github.com/gjtorikian","followers_url":"https://api.github.com/users/gjtorikian/followers","following_url":"https://api.github.com/users/gjtorikian/following{/other_user}","gists_url":"https://api.github.com/users/gjtorikian/gists{/gist_id}","starred_url":"https://api.github.com/users/gjtorikian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gjtorikian/subscriptions","organizations_url":"https://api.github.com/users/gjtorikian/orgs","repos_url":"https://api.github.com/users/gjtorikian/repos","events_url":"https://api.github.com/users/gjtorikian/events{/privacy}","received_events_url":"https://api.github.com/users/gjtorikian/received_events","type":"User","site_admin":true},"created_at":"2016-04-16T18:13:46Z","updated_at":"2016-04-16T18:13:46Z","body":"If you only need a few data structures take a look at https://troydhanson.github.io/uthash/."}}