Cotix/cReddit — pull request #28 by DSMan195276 (2013-09-29 20:36:29+00:00)
Title: Rewrite of libreddit and a little restructuring of the project

Finally able to submit this pull-request. As it was talked about on [pull request #27](https://github.com/Cotix/cReddit/pull/27), I recommend pulling the code into a 'development' branch so the code can sit and be reviewed and worked on before being merged into the main project. The reason I'm submitting it now (Even though there are still things that I think should be changed before a merge into the master branch) is because it can match all the current functionality of creddit (And a bit more).

The diffstat reports 2959 additions and 573 deletions, so sorry about that. Noting that, the large majority of additions is in ./libreddit/, which contains all new code. main.c also contains some changes so that it works with the new libreddit, the Makefile was redone, and the README has a few changes as well to reflect all of these additions.

Because the project has gotten a bit bigger with this addition, I restructured things slightly to make compilation easier. The biggest change in this area is the rewritten Makefile and ./include/ directory. The new Makefile isn't much different except it compiles everything into object (.o) files in the ./build directory and then links them. This results in a much faster compilation if you only change a few files. There is also a ./libreddit/libreddit.mk file which includes rules for creating libreddit.a, and libreddit.mk is included directly into Makefile. Anything in the ./include/ directory is accessible to the entire program and can be included without needing any path prefix. For this reason the new reddit.h file is in this directory, and any other project-wide headers would go here as well. The advantage is that any part of the program can now include "reddit.h" without requiring locating exactly where it is and use it's functionality.

There are things that need to be fixed and worked on, which I've noted in the added ./libreddit/README.md and ./TODO.md files. None of the current issues break the code enough to cause real issues in the running program though, so I submitting this now so others can review it sooner. Most of the missing and TODO things are simply missing functionality or weird cases where unexpected problems may happen (Ex. When there is no internet connection) which aren't yet handled gracefully. I intended to fix these before sending this request, but it may be a few more weeks before I can really sit down and get some more coding in, and I'd rather not wait that long to send this request in since it'll take some time to review.

Now, explaining what all I changed: Instead of having reddit.c and reddit.h, which providing a small set of functions to do some basic handling of the Reddit API, the project now has a subproject of 'libreddit', which is a complete separate library intended to support the Reddit API. As it is a separate library, libreddit is compiled into a static library libreddit.a, and then statically linked to the executable. This isn't a big deal compilation wise, but it does separate two large parts of the program (The interface, and the library for contacting Reddit), which should make the code overall easier to manage. libreddit can also be compiled and used by itself if anybody ever wants to use it for a program besides cReddit, via 'make libreddit'.

libreddit internally has a few different setups meant to reduce the amount of redundancy in the code. The biggest piece is in token.c. The code here implements a generic token parser (More powerful then straight libjsmn, though libjsmn is used by token.c), which basically loops through all the tokens inside of a JSON object, compares each one against an array of structures which specify tokens (struct tokenIdent). If one is found, it checks the tokenIdent for what action should be performed, and then handles it (Ex. Possible actions right now are setting the value in a pointer or calling a function callback). The original reddit.c has lots of copy-pasted code which simply just checked a token for a value, and the handled the result. token.c simply takes that code, implements a more generic version of it, and then takes an array of tokenIdents which specify what to do on each token. The callbacks are for some edge cases which can't be handled generically, or for the case that you have an internal Object (Ex. Replies to Comments are simply more Comment JSON's Objects, which need to be parsed the same as a normal Comment), the callback allows you to run the parser again on that internal object, parse it into a structure and then return and continue parsing the parent object.

In general, there is a single file in ./libreddit/ for each type of object Reddit could return, and a corresponding .h file. The .h file is for specifying functions in these files which anything inside the library can access, but are not accessible outside of the library. For parsing Link's you have link.c and link.h, everything involving users is in user.c and user.h, comments in comment.c and comment.h, etc. Most of these files have fairly small functions which simply setup an array of tokenIdents, and then call the parser in token.c to handle the actual parsing (So, very few parts of code besides token.c actually touch the JSON).

For main.c, it has a few new options. Pressing 'ENTER' on a selected Link will split the screen with the Link's selftext (or URL, if it's just a url) in the bottom half of the screen, and the list of links in the top half. Pressing 'L' will load up the next links in the list (Ex. Usually Links 25 to 50). Pressing 'u' will reset the list of links and load up the first 25 again (If you want to check if new Links are in the top list). Pressing 'c' will take you to comments screen where there is a list of comments in a indented fashion like on Reddit.com (I indent to add in the Line characters, but haven't gotten the chance yet). In this screen, 'q' will exit it and 'ENTER' will split the screen and show you the body text of the current comment.

If you find any glaring issues or obvious things that should be changed, please let me know. I've already checked that there are no memory leaks or issues beyond what I've documented, but it never hurts to check again. If anything, please compile the code and let me know if that goes ok. I believe I've changed a few of the key-presses on the Link screen and comment screen (Because of the differences in the layouts). If you have better recommendations for the key-presses for the various actions I'd be glad to hear your ideas.