. ,--._
.\'-__( )/
\_ ;
\_ / Introduction
-<__,--'' ----================================================================================--------
Tweet With C (TWC) is a C99-compatible library for using the Twitter API. It is designed to allow you, the programmer, to interact with the API at a variety of levels, from raw cURL calls to structured and typechecked functions that marshal the parameters and block until a response is given.
cURL is the sole dependency.
Before you can call any twitter API functions, you must create and initialize a
twc_state
instance:
twc_oauth_keys Keys; // Populate with your OAuth Consumer/Token keys
// OAuth pin authentication coming eventually
twc_state Twitter;
twc_Init(&Twitter, Keys);
Now you can call any function in the Twitter API. For example, to double-check your OAuth keys are working:
twc_call_result VerifyResult =
twc_Account_VerifyCredentials(&Twitter, (twc_account_verifycredentials_params){});
printf("Twitter: %.*s\n", (int)VerifyResult.Data.Size, VerifyResult.Data.Ptr);
And of course, to make a tweet:
twc_call_result TweetResult =
twc_Statuses_Update(&Twitter, twc_ToString("just setting up my twttr"), (twc_statuses_update_params){});
printf("Twitter: %.*s\n", (int)TweetResult.Data.Size, TweetResult.Data.Ptr);
Tweet With C returns all API call results as strings (twc_string
). You can
parse them with your own JSON library, or you can parse them with the provided
JSON parser (also used in the code generator):
json_result Result = json_Parse((char*)VerifyResult.Data.Ptr, (int)VerifyResult.Data.Size);
When you're done, to free allocated memory and do cURL cleanup, call twc_Close
:
twc_Close(&Twitter);
twc_InitEx
takes several parameters which you can use to control how memory is
allocated during library use (by default, it uses malloc
and free
):
twc_InitEx(&Twitter, Keys, MyErrorBuffer, sizeof(MyErrorBuffer), MyMalloc, MyFree);
If you don't want to use the provided API functions, or one doesn't yet exist for the endpoint you're trying to access, you can make calls directly:
twc_key_value_list MyParamList = NULL;
// Load up some params...
MyParamList = twc_KeyValueList_InsertSorted(ParamList, &SomeKeyValue);
twc_MakeCall(&Twitter, TWC_HTTP_GET, "https://api.twitter.com/42.0/undocumented.json", MyParamList);
In the current version of the library, all API calls are synchronous (blocking). In the future, support may be added for asynchronous calls based on cURL's support for the same.
If you can't wait, you may want to look at twitter.c
to see how twc_MakeCall
is implemented. All of the functions it calls are exposed in this interface, so
you can use the existing helper functions in your own version of it.
. ,--._
.\'-__( )/
\_ ;
\_ / Building
-<__,--'' ----================================================================================--------
The Makefile
builds libtwc.a
for static linking. Dynamic linking is not
supported at this time.
libtwc.a
is built by first building the code generator, twc_codegen
. The
code generator takes 2 arguments:
-
<Template file>
-- file where the serialization templates are defined. Most likelycode/twitter.c
. -
<API Schema>
-- JSON file where the latest API schema is stored. Most likelyapi.json
.
New API schemas may be generated by running the TwitterDoc script. Be aware that future revisions of the Twitter API may introduce parameters that do not yet have corresponding types in this library, or endpoints which require different ways of making requests.
The version of api.json
included in this repository is always guaranteed to
produce good code when given to the code generator. Similarly, the
twitter_api.c
and twitter_api.h
provided with the repository are guaranteed
to be working productions based on the api.json
in the repository. If for some
reason the code generator does not work for you, they are your backup plan.
To build on Windows, you will need either Visual Studio with C++ support installed, or the Visual C++ Build Tools.
Only compiling with VS 2015 has been tested. Later versions should be fine, earlier versions may need additional support.
The command-line build tools are only available once vcvarsall.bat
from
your VS installation has been run. For many Visual Studio installations, it may
be easier to simply use the 'Visual Studio Command Prompt' shortcut that is
often created when it installs. If this is not possible, or you wish to run it
from an existing prompt, look for vcvarsall.bat
in a directory similar to
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
.
After that, you can simply execute build.bat
from the directory where you
cloned the repository.
. ,--._
.\'-__( )/
\_ ;
\_ / Contributing
-<__,--'' ----================================================================================--------
Pull requests and issues are always welcome! However, there are a few things to understand before you attempt to start contributing:
-
Use of a code generator results in some unorthodox constructs throughout the codebase. If something seems suspect, please make sure it is not just a benign side effect of code generation, formatting, etc.
-
The code style for this project is a bit unusual. However, please try to follow it in your contributions so that the project remains internally consistent. See below for guidelines.
Types are snake_case
. e.g. twc_string
.
Asterisk goes with the type. e.g. const char*
.
Option types get a $ at the end. e.g. twc_string$
.
Variables and struct fields are PascalCase
. e.g. State->Keys
To avoid namespace pollution, all functions exported from the library are
prefixed with twc_
and thereafter use PascalCase
. e.g. twc_MakeCall
For readability, separate parts of a function name where you might use a
namespace separator in C++. For example, twc_KeyValueList_Append
and
twc_KeyValueList_InsertSorted
are two operations on a twc_key_value_list
,
and so are in the same conceptual 'namespace'.
Prefer verbosity over abbreviation. Code explains itself better if the names are readable and make sense in context.
Prefer explicit over implicit. Invisible behavior makes for invisible bugs.
Prefer stack over heap. Most allocations are small and last the lifetime of the function call. Security problems can be avoided by careful use of length parameters. Clients may not be using the CRT heap.
Functions that write to a buffer parameter should also return the amount of space in the buffer they use up, and should work correctly if the buffer passed is NULL.
Clever is good, but simple is better.
Simple is good, but robust is better.
Robust is good, but maintainable is better.
Tradeoffs are contextual.
Code is data.
Go forth, and contribute.