mirror of https://github.com/GOSTSec/sgminer
Con Kolivas
11 years ago
19 changed files with 1 additions and 3043 deletions
@ -1,20 +0,0 @@ |
|||||||
EXTRA_DIST = conf.py apiref.rst changes.rst conformance.rst \
|
|
||||||
gettingstarted.rst github_commits.c index.rst portability.rst \
|
|
||||||
tutorial.rst upgrading.rst ext/refcounting.py |
|
||||||
|
|
||||||
SPHINXBUILD = sphinx-build |
|
||||||
SPHINXOPTS = -d _build/doctrees $(SPHINXOPTS_EXTRA) |
|
||||||
|
|
||||||
html-local: |
|
||||||
$(SPHINXBUILD) -b html $(SPHINXOPTS) $(srcdir) _build/html |
|
||||||
|
|
||||||
install-html-local: html |
|
||||||
mkdir -p $(DESTDIR)$(htmldir) |
|
||||||
cp -r _build/html $(DESTDIR)$(htmldir) |
|
||||||
|
|
||||||
uninstall-local: |
|
||||||
rm -rf $(DESTDIR)$(htmldir) |
|
||||||
|
|
||||||
clean-local: |
|
||||||
rm -rf _build |
|
||||||
rm -f ext/refcounting.pyc |
|
@ -1,5 +0,0 @@ |
|||||||
To build the documentation, invoke |
|
||||||
|
|
||||||
make html |
|
||||||
|
|
||||||
Then point your browser to _build/html/index.html. |
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +0,0 @@ |
|||||||
****************** |
|
||||||
Changes in Jansson |
|
||||||
****************** |
|
||||||
|
|
||||||
.. include:: ../CHANGES |
|
@ -1,217 +0,0 @@ |
|||||||
# -*- coding: utf-8 -*- |
|
||||||
# |
|
||||||
# Jansson documentation build configuration file, created by |
|
||||||
# sphinx-quickstart on Sun Sep 5 21:47:20 2010. |
|
||||||
# |
|
||||||
# This file is execfile()d with the current directory set to its containing dir. |
|
||||||
# |
|
||||||
# Note that not all possible configuration values are present in this |
|
||||||
# autogenerated file. |
|
||||||
# |
|
||||||
# All configuration values have a default; values that are commented out |
|
||||||
# serve to show the default. |
|
||||||
|
|
||||||
import sys, os |
|
||||||
|
|
||||||
# If extensions (or modules to document with autodoc) are in another directory, |
|
||||||
# add these directories to sys.path here. If the directory is relative to the |
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here. |
|
||||||
sys.path.insert(0, os.path.abspath('ext')) |
|
||||||
|
|
||||||
# -- General configuration ----------------------------------------------------- |
|
||||||
|
|
||||||
# If your documentation needs a minimal Sphinx version, state it here. |
|
||||||
needs_sphinx = '1.0' |
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be extensions |
|
||||||
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. |
|
||||||
extensions = ['refcounting'] |
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory. |
|
||||||
templates_path = ['_templates'] |
|
||||||
|
|
||||||
# The suffix of source filenames. |
|
||||||
source_suffix = '.rst' |
|
||||||
|
|
||||||
# The encoding of source files. |
|
||||||
#source_encoding = 'utf-8-sig' |
|
||||||
|
|
||||||
# The master toctree document. |
|
||||||
master_doc = 'index' |
|
||||||
|
|
||||||
# General information about the project. |
|
||||||
project = u'Jansson' |
|
||||||
copyright = u'2009-2013, Petri Lehtinen' |
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for |
|
||||||
# |version| and |release|, also used in various other places throughout the |
|
||||||
# built documents. |
|
||||||
# |
|
||||||
# The short X.Y version. |
|
||||||
version = '2.5' |
|
||||||
# The full version, including alpha/beta/rc tags. |
|
||||||
release = version |
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation |
|
||||||
# for a list of supported languages. |
|
||||||
#language = None |
|
||||||
|
|
||||||
# There are two options for replacing |today|: either, you set today to some |
|
||||||
# non-false value, then it is used: |
|
||||||
#today = '' |
|
||||||
# Else, today_fmt is used as the format for a strftime call. |
|
||||||
#today_fmt = '%B %d, %Y' |
|
||||||
|
|
||||||
# List of patterns, relative to source directory, that match files and |
|
||||||
# directories to ignore when looking for source files. |
|
||||||
exclude_patterns = ['_build'] |
|
||||||
|
|
||||||
# The reST default role (used for this markup: `text`) to use for all documents. |
|
||||||
default_role = 'c:func' |
|
||||||
primary_domain = 'c' |
|
||||||
|
|
||||||
# If true, '()' will be appended to :func: etc. cross-reference text. |
|
||||||
#add_function_parentheses = True |
|
||||||
|
|
||||||
# If true, the current module name will be prepended to all description |
|
||||||
# unit titles (such as .. function::). |
|
||||||
#add_module_names = True |
|
||||||
|
|
||||||
# If true, sectionauthor and moduleauthor directives will be shown in the |
|
||||||
# output. They are ignored by default. |
|
||||||
#show_authors = False |
|
||||||
|
|
||||||
# The name of the Pygments (syntax highlighting) style to use. |
|
||||||
pygments_style = 'sphinx' |
|
||||||
|
|
||||||
# A list of ignored prefixes for module index sorting. |
|
||||||
#modindex_common_prefix = [] |
|
||||||
|
|
||||||
|
|
||||||
# -- Options for HTML output --------------------------------------------------- |
|
||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for |
|
||||||
# a list of builtin themes. |
|
||||||
#html_theme = 'default' |
|
||||||
|
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme |
|
||||||
# further. For a list of options available for each theme, see the |
|
||||||
# documentation. |
|
||||||
#html_theme_options = {} |
|
||||||
|
|
||||||
# Add any paths that contain custom themes here, relative to this directory. |
|
||||||
#html_theme_path = [] |
|
||||||
|
|
||||||
# The name for this set of Sphinx documents. If None, it defaults to |
|
||||||
# "<project> v<release> documentation". |
|
||||||
#html_title = None |
|
||||||
|
|
||||||
# A shorter title for the navigation bar. Default is the same as html_title. |
|
||||||
#html_short_title = None |
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top |
|
||||||
# of the sidebar. |
|
||||||
#html_logo = None |
|
||||||
|
|
||||||
# The name of an image file (within the static path) to use as favicon of the |
|
||||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 |
|
||||||
# pixels large. |
|
||||||
#html_favicon = None |
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here, |
|
||||||
# relative to this directory. They are copied after the builtin static files, |
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css". |
|
||||||
#html_static_path = ['_static'] |
|
||||||
|
|
||||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, |
|
||||||
# using the given strftime format. |
|
||||||
#html_last_updated_fmt = '%b %d, %Y' |
|
||||||
|
|
||||||
# If true, SmartyPants will be used to convert quotes and dashes to |
|
||||||
# typographically correct entities. |
|
||||||
#html_use_smartypants = True |
|
||||||
|
|
||||||
# Custom sidebar templates, maps document names to template names. |
|
||||||
#html_sidebars = {} |
|
||||||
|
|
||||||
# Additional templates that should be rendered to pages, maps page names to |
|
||||||
# template names. |
|
||||||
#html_additional_pages = {} |
|
||||||
|
|
||||||
# If false, no module index is generated. |
|
||||||
#html_domain_indices = True |
|
||||||
|
|
||||||
# If false, no index is generated. |
|
||||||
#html_use_index = True |
|
||||||
|
|
||||||
# If true, the index is split into individual pages for each letter. |
|
||||||
#html_split_index = False |
|
||||||
|
|
||||||
# If true, links to the reST sources are added to the pages. |
|
||||||
#html_show_sourcelink = True |
|
||||||
|
|
||||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. |
|
||||||
#html_show_sphinx = True |
|
||||||
|
|
||||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. |
|
||||||
#html_show_copyright = True |
|
||||||
|
|
||||||
# If true, an OpenSearch description file will be output, and all pages will |
|
||||||
# contain a <link> tag referring to it. The value of this option must be the |
|
||||||
# base URL from which the finished HTML is served. |
|
||||||
#html_use_opensearch = '' |
|
||||||
|
|
||||||
# This is the file name suffix for HTML files (e.g. ".xhtml"). |
|
||||||
#html_file_suffix = None |
|
||||||
|
|
||||||
# Output file base name for HTML help builder. |
|
||||||
htmlhelp_basename = 'Janssondoc' |
|
||||||
|
|
||||||
|
|
||||||
# -- Options for LaTeX output -------------------------------------------------- |
|
||||||
|
|
||||||
# The paper size ('letter' or 'a4'). |
|
||||||
#latex_paper_size = 'letter' |
|
||||||
|
|
||||||
# The font size ('10pt', '11pt' or '12pt'). |
|
||||||
#latex_font_size = '10pt' |
|
||||||
|
|
||||||
# Grouping the document tree into LaTeX files. List of tuples |
|
||||||
# (source start file, target name, title, author, documentclass [howto/manual]). |
|
||||||
latex_documents = [ |
|
||||||
('index', 'Jansson.tex', u'Jansson Documentation', |
|
||||||
u'Petri Lehtinen', 'manual'), |
|
||||||
] |
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top of |
|
||||||
# the title page. |
|
||||||
#latex_logo = None |
|
||||||
|
|
||||||
# For "manual" documents, if this is true, then toplevel headings are parts, |
|
||||||
# not chapters. |
|
||||||
#latex_use_parts = False |
|
||||||
|
|
||||||
# If true, show page references after internal links. |
|
||||||
#latex_show_pagerefs = False |
|
||||||
|
|
||||||
# If true, show URL addresses after external links. |
|
||||||
#latex_show_urls = False |
|
||||||
|
|
||||||
# Additional stuff for the LaTeX preamble. |
|
||||||
#latex_preamble = '' |
|
||||||
|
|
||||||
# Documents to append as an appendix to all manuals. |
|
||||||
#latex_appendices = [] |
|
||||||
|
|
||||||
# If false, no module index is generated. |
|
||||||
#latex_domain_indices = True |
|
||||||
|
|
||||||
|
|
||||||
# -- Options for manual page output -------------------------------------------- |
|
||||||
|
|
||||||
# One entry per manual page. List of tuples |
|
||||||
# (source start file, name, description, authors, manual section). |
|
||||||
man_pages = [ |
|
||||||
('index', 'jansson', u'Jansson Documentation', |
|
||||||
[u'Petri Lehtinen'], 1) |
|
||||||
] |
|
@ -1,114 +0,0 @@ |
|||||||
.. _rfc-conformance: |
|
||||||
|
|
||||||
*************** |
|
||||||
RFC Conformance |
|
||||||
*************** |
|
||||||
|
|
||||||
JSON is specified in :rfc:`4627`, *"The application/json Media Type |
|
||||||
for JavaScript Object Notation (JSON)"*. |
|
||||||
|
|
||||||
Character Encoding |
|
||||||
================== |
|
||||||
|
|
||||||
Jansson only supports UTF-8 encoded JSON texts. It does not support or |
|
||||||
auto-detect any of the other encodings mentioned in the RFC, namely |
|
||||||
UTF-16LE, UTF-16BE, UTF-32LE or UTF-32BE. Pure ASCII is supported, as |
|
||||||
it's a subset of UTF-8. |
|
||||||
|
|
||||||
Strings |
|
||||||
======= |
|
||||||
|
|
||||||
JSON strings are mapped to C-style null-terminated character arrays, |
|
||||||
and UTF-8 encoding is used internally. Strings may not contain |
|
||||||
embedded null characters, not even escaped ones. |
|
||||||
|
|
||||||
For example, trying to decode the following JSON text leads to a parse |
|
||||||
error:: |
|
||||||
|
|
||||||
["this string contains the null character: \u0000"] |
|
||||||
|
|
||||||
All other Unicode codepoints U+0001 through U+10FFFF are allowed. |
|
||||||
|
|
||||||
Unicode normalization or any other transformation is never performed |
|
||||||
on any strings (string values or object keys). When checking for |
|
||||||
equivalence of strings or object keys, the comparison is performed |
|
||||||
byte by byte between the original UTF-8 representations of the |
|
||||||
strings. |
|
||||||
|
|
||||||
Numbers |
|
||||||
======= |
|
||||||
|
|
||||||
.. _real-vs-integer: |
|
||||||
|
|
||||||
Real vs. Integer |
|
||||||
---------------- |
|
||||||
|
|
||||||
JSON makes no distinction between real and integer numbers; Jansson |
|
||||||
does. Real numbers are mapped to the ``double`` type and integers to |
|
||||||
the ``json_int_t`` type, which is a typedef of ``long long`` or |
|
||||||
``long``, depending on whether ``long long`` is supported by your |
|
||||||
compiler or not. |
|
||||||
|
|
||||||
A JSON number is considered to be a real number if its lexical |
|
||||||
representation includes one of ``e``, ``E``, or ``.``; regardless if |
|
||||||
its actual numeric value is a true integer (e.g., all of ``1E6``, |
|
||||||
``3.0``, ``400E-2``, and ``3.14E3`` are mathematical integers, but |
|
||||||
will be treated as real values). With the ``JSON_DECODE_INT_AS_REAL`` |
|
||||||
decoder flag set all numbers are interpreted as real. |
|
||||||
|
|
||||||
All other JSON numbers are considered integers. |
|
||||||
|
|
||||||
When encoding to JSON, real values are always represented |
|
||||||
with a fractional part; e.g., the ``double`` value 3.0 will be |
|
||||||
represented in JSON as ``3.0``, not ``3``. |
|
||||||
|
|
||||||
Overflow, Underflow & Precision |
|
||||||
------------------------------- |
|
||||||
|
|
||||||
Real numbers whose absolute values are too small to be represented in |
|
||||||
a C ``double`` will be silently estimated with 0.0. Thus, depending on |
|
||||||
platform, JSON numbers very close to zero such as 1E-999 may result in |
|
||||||
0.0. |
|
||||||
|
|
||||||
Real numbers whose absolute values are too large to be represented in |
|
||||||
a C ``double`` will result in an overflow error (a JSON decoding |
|
||||||
error). Thus, depending on platform, JSON numbers like 1E+999 or |
|
||||||
-1E+999 may result in a parsing error. |
|
||||||
|
|
||||||
Likewise, integer numbers whose absolute values are too large to be |
|
||||||
represented in the ``json_int_t`` type (see above) will result in an |
|
||||||
overflow error (a JSON decoding error). Thus, depending on platform, |
|
||||||
JSON numbers like 1000000000000000 may result in parsing error. |
|
||||||
|
|
||||||
Parsing JSON real numbers may result in a loss of precision. As long |
|
||||||
as overflow does not occur (i.e. a total loss of precision), the |
|
||||||
rounded approximate value is silently used. Thus the JSON number |
|
||||||
1.000000000000000005 may, depending on platform, result in the |
|
||||||
``double`` value 1.0. |
|
||||||
|
|
||||||
Signed zeros |
|
||||||
------------ |
|
||||||
|
|
||||||
JSON makes no statement about what a number means; however Javascript |
|
||||||
(ECMAscript) does state that +0.0 and -0.0 must be treated as being |
|
||||||
distinct values, i.e. -0.0 |not-equal| 0.0. Jansson relies on the |
|
||||||
underlying floating point library in the C environment in which it is |
|
||||||
compiled. Therefore it is platform-dependent whether 0.0 and -0.0 will |
|
||||||
be distinct values. Most platforms that use the IEEE 754 |
|
||||||
floating-point standard will support signed zeros. |
|
||||||
|
|
||||||
Note that this only applies to floating-point; neither JSON, C, or |
|
||||||
IEEE support the concept of signed integer zeros. |
|
||||||
|
|
||||||
.. |not-equal| unicode:: U+2260 |
|
||||||
|
|
||||||
Types |
|
||||||
----- |
|
||||||
|
|
||||||
No support is provided in Jansson for any C numeric types other than |
|
||||||
``json_int_t`` and ``double``. This excludes things such as unsigned |
|
||||||
types, ``long double``, etc. Obviously, shorter types like ``short``, |
|
||||||
``int``, ``long`` (if ``json_int_t`` is ``long long``) and ``float`` |
|
||||||
are implicitly handled via the ordinary C type coercion rules (subject |
|
||||||
to overflow semantics). Also, no support or hooks are provided for any |
|
||||||
supplemental "bignum" type add-on packages. |
|
@ -1,59 +0,0 @@ |
|||||||
""" |
|
||||||
refcounting |
|
||||||
~~~~~~~~~~~ |
|
||||||
|
|
||||||
Reference count annotations for C API functions. Has the same |
|
||||||
result as the sphinx.ext.refcounting extension but works for all |
|
||||||
functions regardless of the signature, and the reference counting |
|
||||||
information is written inline with the documentation instead of a |
|
||||||
separate file. |
|
||||||
|
|
||||||
Adds a new directive "refcounting". The directive has no content |
|
||||||
and one required positional parameter:: "new" or "borrow". |
|
||||||
|
|
||||||
Example: |
|
||||||
|
|
||||||
.. cfunction:: json_t *json_object(void) |
|
||||||
|
|
||||||
.. refcounting:: new |
|
||||||
|
|
||||||
<description of the json_object function> |
|
||||||
|
|
||||||
:copyright: Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org> |
|
||||||
:license: MIT, see LICENSE for details. |
|
||||||
""" |
|
||||||
|
|
||||||
from docutils import nodes |
|
||||||
|
|
||||||
class refcounting(nodes.emphasis): pass |
|
||||||
|
|
||||||
def visit(self, node): |
|
||||||
self.visit_emphasis(node) |
|
||||||
|
|
||||||
def depart(self, node): |
|
||||||
self.depart_emphasis(node) |
|
||||||
|
|
||||||
def html_visit(self, node): |
|
||||||
self.body.append(self.starttag(node, 'em', '', CLASS='refcount')) |
|
||||||
|
|
||||||
def html_depart(self, node): |
|
||||||
self.body.append('</em>') |
|
||||||
|
|
||||||
|
|
||||||
def refcounting_directive(name, arguments, options, content, lineno, |
|
||||||
content_offset, block_text, state, state_machine): |
|
||||||
if arguments[0] == 'borrow': |
|
||||||
text = 'Return value: Borrowed reference.' |
|
||||||
elif arguments[0] == 'new': |
|
||||||
text = 'Return value: New reference.' |
|
||||||
else: |
|
||||||
raise Error('Valid arguments: new, borrow') |
|
||||||
|
|
||||||
return [refcounting(text, text)] |
|
||||||
|
|
||||||
def setup(app): |
|
||||||
app.add_node(refcounting, |
|
||||||
html=(html_visit, html_depart), |
|
||||||
latex=(visit, depart), |
|
||||||
text=(visit, depart)) |
|
||||||
app.add_directive('refcounting', refcounting_directive, 0, (1, 0, 0)) |
|
@ -1,237 +0,0 @@ |
|||||||
*************** |
|
||||||
Getting Started |
|
||||||
*************** |
|
||||||
|
|
||||||
.. highlight:: c |
|
||||||
|
|
||||||
Compiling and Installing Jansson |
|
||||||
================================ |
|
||||||
|
|
||||||
The Jansson source is available at |
|
||||||
http://www.digip.org/jansson/releases/. |
|
||||||
|
|
||||||
Unix-like systems (including MinGW) |
|
||||||
----------------------------------- |
|
||||||
|
|
||||||
Unpack the source tarball and change to the source directory: |
|
||||||
|
|
||||||
.. parsed-literal:: |
|
||||||
|
|
||||||
bunzip2 -c jansson-|release|.tar.bz2 | tar xf - |
|
||||||
cd jansson-|release| |
|
||||||
|
|
||||||
The source uses GNU Autotools (autoconf_, automake_, libtool_), so |
|
||||||
compiling and installing is extremely simple:: |
|
||||||
|
|
||||||
./configure |
|
||||||
make |
|
||||||
make check |
|
||||||
make install |
|
||||||
|
|
||||||
To change the destination directory (``/usr/local`` by default), use |
|
||||||
the ``--prefix=DIR`` argument to ``./configure``. See ``./configure |
|
||||||
--help`` for the list of all possible installation options. (There are |
|
||||||
no options to customize the resulting Jansson binary.) |
|
||||||
|
|
||||||
The command ``make check`` runs the test suite distributed with |
|
||||||
Jansson. This step is not strictly necessary, but it may find possible |
|
||||||
problems that Jansson has on your platform. If any problems are found, |
|
||||||
please report them. |
|
||||||
|
|
||||||
If you obtained the source from a Git repository (or any other source |
|
||||||
control system), there's no ``./configure`` script as it's not kept in |
|
||||||
version control. To create the script, the build system needs to be |
|
||||||
bootstrapped. There are many ways to do this, but the easiest one is |
|
||||||
to use ``autoreconf``:: |
|
||||||
|
|
||||||
autoreconf -vi |
|
||||||
|
|
||||||
This command creates the ``./configure`` script, which can then be |
|
||||||
used as described above. |
|
||||||
|
|
||||||
.. _autoconf: http://www.gnu.org/software/autoconf/ |
|
||||||
.. _automake: http://www.gnu.org/software/automake/ |
|
||||||
.. _libtool: http://www.gnu.org/software/libtool/ |
|
||||||
|
|
||||||
|
|
||||||
.. _build-cmake: |
|
||||||
|
|
||||||
CMake (various platforms, including Windows) |
|
||||||
-------------------------------------------- |
|
||||||
|
|
||||||
Jansson can be built using CMake_. Create a build directory for an |
|
||||||
out-of-tree build, change to that directory, and run ``cmake`` (or ``ccmake``, |
|
||||||
``cmake-gui``, or similar) to configure the project. |
|
||||||
|
|
||||||
See the examples below for more detailed information. |
|
||||||
|
|
||||||
.. note:: In the below examples ``..`` is used as an argument for ``cmake``. |
|
||||||
This is simply the path to the jansson project root directory. |
|
||||||
In the example it is assumed you've created a sub-directory ``build`` |
|
||||||
and are using that. You could use any path you want. |
|
||||||
|
|
||||||
.. _build-cmake-unix: |
|
||||||
|
|
||||||
Unix (Make files) |
|
||||||
^^^^^^^^^^^^^^^^^ |
|
||||||
Generating make files on unix: |
|
||||||
|
|
||||||
.. parsed-literal:: |
|
||||||
|
|
||||||
bunzip2 -c jansson-|release|.tar.bz2 | tar xf - |
|
||||||
cd jansson-|release| |
|
||||||
|
|
||||||
mkdir build |
|
||||||
cd build |
|
||||||
cmake .. # or `ccmake ..` for a GUI. |
|
||||||
|
|
||||||
Then to build:: |
|
||||||
|
|
||||||
make |
|
||||||
make check |
|
||||||
make install |
|
||||||
|
|
||||||
Windows (Visual Studio) |
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^ |
|
||||||
Creating Visual Studio project files from the command line: |
|
||||||
|
|
||||||
.. parsed-literal:: |
|
||||||
|
|
||||||
<unpack> |
|
||||||
cd jansson-|release| |
|
||||||
|
|
||||||
md build |
|
||||||
cd build |
|
||||||
cmake -G "Visual Studio 10" .. |
|
||||||
|
|
||||||
You will now have a *Visual Studio Solution* in your build directory. |
|
||||||
To run the unit tests build the ``RUN_TESTS`` project. |
|
||||||
|
|
||||||
If you prefer a GUI the ``cmake`` line in the above example can |
|
||||||
be replaced with:: |
|
||||||
|
|
||||||
cmake-gui .. |
|
||||||
|
|
||||||
For command line help (including a list of available generators) |
|
||||||
for CMake_ simply run:: |
|
||||||
|
|
||||||
cmake |
|
||||||
|
|
||||||
To list available CMake_ settings (and what they are currently set to) |
|
||||||
for the project, run:: |
|
||||||
|
|
||||||
cmake -LH .. |
|
||||||
|
|
||||||
Mac OSX (Xcode) |
|
||||||
^^^^^^^^^^^^^^^ |
|
||||||
If you prefer using Xcode instead of make files on OSX, |
|
||||||
do the following. (Use the same steps as |
|
||||||
for :ref:`Unix <build-cmake-unix>`):: |
|
||||||
|
|
||||||
... |
|
||||||
cmake -G "Xcode" .. |
|
||||||
|
|
||||||
Additional CMake settings |
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^ |
|
||||||
|
|
||||||
Shared library |
|
||||||
"""""""""""""" |
|
||||||
By default the CMake_ project will generate build files for building the |
|
||||||
static library. To build the shared version use:: |
|
||||||
|
|
||||||
... |
|
||||||
cmake -DBUILD_SHARED=1 .. |
|
||||||
|
|
||||||
Changing install directory (same as autoconf --prefix) |
|
||||||
"""""""""""""""""""""""""""""""""""""""""""""""""""""" |
|
||||||
Just as with the autoconf_ project you can change the destination directory |
|
||||||
for ``make install``. The equivalent for autoconfs ``./configure --prefix`` |
|
||||||
in CMake_ is:: |
|
||||||
|
|
||||||
... |
|
||||||
cmake -DCMAKE_INSTALL_PREFIX:PATH=/some/other/path .. |
|
||||||
make install |
|
||||||
|
|
||||||
.. _CMake: http://www.cmake.org |
|
||||||
|
|
||||||
Android |
|
||||||
------- |
|
||||||
|
|
||||||
Jansson can be built for Android platforms. Android.mk is in the |
|
||||||
source root directory. The configuration header file is located in the |
|
||||||
``android`` directory in the source distribution. |
|
||||||
|
|
||||||
|
|
||||||
Windows |
|
||||||
------- |
|
||||||
|
|
||||||
**This method is deprecated**. Using :ref:`CMake <build-cmake>` is now |
|
||||||
preferred. |
|
||||||
|
|
||||||
Jansson can be built with Visual Studio 2010 (and probably newer |
|
||||||
versions, too). The solution and project files are in the |
|
||||||
``win32/vs2010/`` directory in the source distribution. |
|
||||||
|
|
||||||
|
|
||||||
Other Systems |
|
||||||
------------- |
|
||||||
|
|
||||||
On non Unix-like systems, you may be unable to run the ``./configure`` |
|
||||||
script. In this case, follow these steps. All the files mentioned can |
|
||||||
be found in the ``src/`` directory. |
|
||||||
|
|
||||||
1. Create ``jansson_config.h`` (which has some platform-specific |
|
||||||
parameters that are normally filled in by the ``./configure`` |
|
||||||
script). Edit ``jansson_config.h.in``, replacing all ``@variable@`` |
|
||||||
placeholders, and rename the file to ``jansson_config.h``. |
|
||||||
|
|
||||||
2. Make ``jansson.h`` and ``jansson_config.h`` available to the |
|
||||||
compiler, so that they can be found when compiling programs that |
|
||||||
use Jansson. |
|
||||||
|
|
||||||
3. Compile all the ``.c`` files (in the ``src/`` directory) into a |
|
||||||
library file. Make the library available to the compiler, as in |
|
||||||
step 2. |
|
||||||
|
|
||||||
|
|
||||||
Building the Documentation |
|
||||||
-------------------------- |
|
||||||
|
|
||||||
(This subsection describes how to build the HTML documentation you are |
|
||||||
currently reading, so it can be safely skipped.) |
|
||||||
|
|
||||||
Documentation is in the ``doc/`` subdirectory. It's written in |
|
||||||
reStructuredText_ with Sphinx_ annotations. To generate the HTML |
|
||||||
documentation, invoke:: |
|
||||||
|
|
||||||
make html |
|
||||||
|
|
||||||
and point your browser to ``doc/_build/html/index.html``. Sphinx_ 1.0 |
|
||||||
or newer is required to generate the documentation. |
|
||||||
|
|
||||||
.. _reStructuredText: http://docutils.sourceforge.net/rst.html |
|
||||||
.. _Sphinx: http://sphinx.pocoo.org/ |
|
||||||
|
|
||||||
|
|
||||||
Compiling Programs that Use Jansson |
|
||||||
=================================== |
|
||||||
|
|
||||||
Jansson involves one C header file, :file:`jansson.h`, so it's enough |
|
||||||
to put the line |
|
||||||
|
|
||||||
:: |
|
||||||
|
|
||||||
#include <jansson.h> |
|
||||||
|
|
||||||
in the beginning of every source file that uses Jansson. |
|
||||||
|
|
||||||
There's also just one library to link with, ``libjansson``. Compile and |
|
||||||
link the program as follows:: |
|
||||||
|
|
||||||
cc -o prog prog.c -ljansson |
|
||||||
|
|
||||||
Starting from version 1.2, there's also support for pkg-config_:: |
|
||||||
|
|
||||||
cc -o prog prog.c `pkg-config --cflags --libs jansson` |
|
||||||
|
|
||||||
.. _pkg-config: http://pkg-config.freedesktop.org/ |
|
@ -1,192 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (c) 2009-2013 Petri Lehtinen <petri@digip.org> |
|
||||||
* |
|
||||||
* Jansson is free software; you can redistribute it and/or modify |
|
||||||
* it under the terms of the MIT license. See LICENSE for details. |
|
||||||
*/ |
|
||||||
|
|
||||||
#include <stdlib.h> |
|
||||||
#include <string.h> |
|
||||||
|
|
||||||
#include <jansson.h> |
|
||||||
#include <curl/curl.h> |
|
||||||
|
|
||||||
#define BUFFER_SIZE (256 * 1024) /* 256 KB */ |
|
||||||
|
|
||||||
#define URL_FORMAT "https://api.github.com/repos/%s/%s/commits"
|
|
||||||
#define URL_SIZE 256 |
|
||||||
|
|
||||||
/* Return the offset of the first newline in text or the length of
|
|
||||||
text if there's no newline */ |
|
||||||
static int newline_offset(const char *text) |
|
||||||
{ |
|
||||||
const char *newline = strchr(text, '\n'); |
|
||||||
if(!newline) |
|
||||||
return strlen(text); |
|
||||||
else |
|
||||||
return (int)(newline - text); |
|
||||||
} |
|
||||||
|
|
||||||
struct write_result |
|
||||||
{ |
|
||||||
char *data; |
|
||||||
int pos; |
|
||||||
}; |
|
||||||
|
|
||||||
static size_t write_response(void *ptr, size_t size, size_t nmemb, void *stream) |
|
||||||
{ |
|
||||||
struct write_result *result = (struct write_result *)stream; |
|
||||||
|
|
||||||
if(result->pos + size * nmemb >= BUFFER_SIZE - 1) |
|
||||||
{ |
|
||||||
fprintf(stderr, "error: too small buffer\n"); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
memcpy(result->data + result->pos, ptr, size * nmemb); |
|
||||||
result->pos += size * nmemb; |
|
||||||
|
|
||||||
return size * nmemb; |
|
||||||
} |
|
||||||
|
|
||||||
static char *request(const char *url) |
|
||||||
{ |
|
||||||
CURL *curl = NULL; |
|
||||||
CURLcode status; |
|
||||||
char *data = NULL; |
|
||||||
long code; |
|
||||||
|
|
||||||
curl_global_init(CURL_GLOBAL_ALL); |
|
||||||
curl = curl_easy_init(); |
|
||||||
if(!curl) |
|
||||||
goto error; |
|
||||||
|
|
||||||
data = malloc(BUFFER_SIZE); |
|
||||||
if(!data) |
|
||||||
goto error; |
|
||||||
|
|
||||||
struct write_result write_result = { |
|
||||||
.data = data, |
|
||||||
.pos = 0 |
|
||||||
}; |
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url); |
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_response); |
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &write_result); |
|
||||||
|
|
||||||
status = curl_easy_perform(curl); |
|
||||||
if(status != 0) |
|
||||||
{ |
|
||||||
fprintf(stderr, "error: unable to request data from %s:\n", url); |
|
||||||
fprintf(stderr, "%s\n", curl_easy_strerror(status)); |
|
||||||
goto error; |
|
||||||
} |
|
||||||
|
|
||||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code); |
|
||||||
if(code != 200) |
|
||||||
{ |
|
||||||
fprintf(stderr, "error: server responded with code %ld\n", code); |
|
||||||
goto error; |
|
||||||
} |
|
||||||
|
|
||||||
curl_easy_cleanup(curl); |
|
||||||
curl_global_cleanup(); |
|
||||||
|
|
||||||
/* zero-terminate the result */ |
|
||||||
data[write_result.pos] = '\0'; |
|
||||||
|
|
||||||
return data; |
|
||||||
|
|
||||||
error: |
|
||||||
if(data) |
|
||||||
free(data); |
|
||||||
if(curl) |
|
||||||
curl_easy_cleanup(curl); |
|
||||||
curl_global_cleanup(); |
|
||||||
return NULL; |
|
||||||
} |
|
||||||
|
|
||||||
int main(int argc, char *argv[]) |
|
||||||
{ |
|
||||||
size_t i; |
|
||||||
char *text; |
|
||||||
char url[URL_SIZE]; |
|
||||||
|
|
||||||
json_t *root; |
|
||||||
json_error_t error; |
|
||||||
|
|
||||||
if(argc != 3) |
|
||||||
{ |
|
||||||
fprintf(stderr, "usage: %s USER REPOSITORY\n\n", argv[0]); |
|
||||||
fprintf(stderr, "List commits at USER's REPOSITORY.\n\n"); |
|
||||||
return 2; |
|
||||||
} |
|
||||||
|
|
||||||
snprintf(url, URL_SIZE, URL_FORMAT, argv[1], argv[2]); |
|
||||||
|
|
||||||
text = request(url); |
|
||||||
if(!text) |
|
||||||
return 1; |
|
||||||
|
|
||||||
root = json_loads(text, 0, &error); |
|
||||||
free(text); |
|
||||||
|
|
||||||
if(!root) |
|
||||||
{ |
|
||||||
fprintf(stderr, "error: on line %d: %s\n", error.line, error.text); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
|
|
||||||
if(!json_is_array(root)) |
|
||||||
{ |
|
||||||
fprintf(stderr, "error: root is not an array\n"); |
|
||||||
json_decref(root); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
|
|
||||||
for(i = 0; i < json_array_size(root); i++) |
|
||||||
{ |
|
||||||
json_t *data, *sha, *commit, *message; |
|
||||||
const char *message_text; |
|
||||||
|
|
||||||
data = json_array_get(root, i); |
|
||||||
if(!json_is_object(data)) |
|
||||||
{ |
|
||||||
fprintf(stderr, "error: commit data %d is not an object\n", (int)(i + 1)); |
|
||||||
json_decref(root); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
|
|
||||||
sha = json_object_get(data, "sha"); |
|
||||||
if(!json_is_string(sha)) |
|
||||||
{ |
|
||||||
fprintf(stderr, "error: commit %d: sha is not a string\n", (int)(i + 1)); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
|
|
||||||
commit = json_object_get(data, "commit"); |
|
||||||
if(!json_is_object(commit)) |
|
||||||
{ |
|
||||||
fprintf(stderr, "error: commit %d: commit is not an object\n", (int)(i + 1)); |
|
||||||
json_decref(root); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
|
|
||||||
message = json_object_get(commit, "message"); |
|
||||||
if(!json_is_string(message)) |
|
||||||
{ |
|
||||||
fprintf(stderr, "error: commit %d: message is not a string\n", (int)(i + 1)); |
|
||||||
json_decref(root); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
|
|
||||||
message_text = json_string_value(message); |
|
||||||
printf("%.8s %.*s\n", |
|
||||||
json_string_value(sha), |
|
||||||
newline_offset(message_text), |
|
||||||
message_text); |
|
||||||
} |
|
||||||
|
|
||||||
json_decref(root); |
|
||||||
return 0; |
|
||||||
} |
|
@ -1,53 +0,0 @@ |
|||||||
Jansson Documentation |
|
||||||
===================== |
|
||||||
|
|
||||||
This is the documentation for Jansson_ |release|, last updated |today|. |
|
||||||
|
|
||||||
Introduction |
|
||||||
------------ |
|
||||||
|
|
||||||
Jansson_ is a C library for encoding, decoding and manipulating JSON |
|
||||||
data. Its main features and design principles are: |
|
||||||
|
|
||||||
- Simple and intuitive API and data model |
|
||||||
|
|
||||||
- Comprehensive documentation |
|
||||||
|
|
||||||
- No dependencies on other libraries |
|
||||||
|
|
||||||
- Full Unicode support (UTF-8) |
|
||||||
|
|
||||||
- Extensive test suite |
|
||||||
|
|
||||||
Jansson is licensed under the `MIT license`_; see LICENSE in the |
|
||||||
source distribution for details. |
|
||||||
|
|
||||||
Jansson is used in production and its API is stable. It works on |
|
||||||
numerous platforms, including numerous Unix like systems and Windows. |
|
||||||
It's suitable for use on any system, including desktop, server, and |
|
||||||
small embedded systems. |
|
||||||
|
|
||||||
|
|
||||||
.. _`MIT license`: http://www.opensource.org/licenses/mit-license.php |
|
||||||
.. _Jansson: http://www.digip.org/jansson/ |
|
||||||
|
|
||||||
Contents |
|
||||||
-------- |
|
||||||
|
|
||||||
.. toctree:: |
|
||||||
:maxdepth: 2 |
|
||||||
|
|
||||||
gettingstarted |
|
||||||
upgrading |
|
||||||
tutorial |
|
||||||
conformance |
|
||||||
portability |
|
||||||
apiref |
|
||||||
changes |
|
||||||
|
|
||||||
|
|
||||||
Indices and Tables |
|
||||||
================== |
|
||||||
|
|
||||||
* :ref:`genindex` |
|
||||||
* :ref:`search` |
|
@ -1,52 +0,0 @@ |
|||||||
*********** |
|
||||||
Portability |
|
||||||
*********** |
|
||||||
|
|
||||||
Thread safety |
|
||||||
------------- |
|
||||||
|
|
||||||
Jansson is thread safe and has no mutable global state. The only |
|
||||||
exception are the memory allocation functions, that should be set at |
|
||||||
most once, and only on program startup. See |
|
||||||
:ref:`apiref-custom-memory-allocation`. |
|
||||||
|
|
||||||
There's no locking performed inside Jansson's code, so a multithreaded |
|
||||||
program must perform its own locking if JSON values are shared by |
|
||||||
multiple threads. Jansson's reference counting semantics may make this |
|
||||||
a bit harder than it seems, as it's possible to have a reference to a |
|
||||||
value that's also stored inside a list or object. Modifying the |
|
||||||
container (adding or removing values) may trigger concurrent access to |
|
||||||
such values, as containers manage the reference count of their |
|
||||||
contained values. Bugs involving concurrent incrementing or |
|
||||||
decrementing of deference counts may be hard to track. |
|
||||||
|
|
||||||
The encoding functions (:func:`json_dumps()` and friends) track |
|
||||||
reference loops by modifying the internal state of objects and arrays. |
|
||||||
For this reason, encoding functions must not be run on the same JSON |
|
||||||
values in two separate threads at the same time. As already noted |
|
||||||
above, be especially careful if two arrays or objects share their |
|
||||||
contained values with another array or object. |
|
||||||
|
|
||||||
If you want to make sure that two JSON value hierarchies do not |
|
||||||
contain shared values, use :func:`json_deep_copy()` to make copies. |
|
||||||
|
|
||||||
Locale |
|
||||||
------ |
|
||||||
|
|
||||||
Jansson works fine under any locale. |
|
||||||
|
|
||||||
However, if the host program is multithreaded and uses ``setlocale()`` |
|
||||||
to switch the locale in one thread while Jansson is currently encoding |
|
||||||
or decoding JSON data in another thread, the result may be wrong or |
|
||||||
the program may even crash. |
|
||||||
|
|
||||||
Jansson uses locale specific functions for certain string conversions |
|
||||||
in the encoder and decoder, and then converts the locale specific |
|
||||||
values to/from the JSON representation. This fails if the locale |
|
||||||
changes between the string conversion and the locale-to-JSON |
|
||||||
conversion. This can only happen in multithreaded programs that use |
|
||||||
``setlocale()``, because ``setlocale()`` switches the locale for all |
|
||||||
running threads, not only the thread that calls ``setlocale()``. |
|
||||||
|
|
||||||
If your program uses ``setlocale()`` as described above, consider |
|
||||||
using the thread-safe ``uselocale()`` instead. |
|
@ -1,286 +0,0 @@ |
|||||||
.. _tutorial: |
|
||||||
|
|
||||||
******** |
|
||||||
Tutorial |
|
||||||
******** |
|
||||||
|
|
||||||
.. highlight:: c |
|
||||||
|
|
||||||
In this tutorial, we create a program that fetches the latest commits |
|
||||||
of a repository in GitHub_ over the web. `GitHub API`_ uses JSON, so |
|
||||||
the result can be parsed using Jansson. |
|
||||||
|
|
||||||
To stick to the the scope of this tutorial, we will only cover the the |
|
||||||
parts of the program related to handling JSON data. For the best user |
|
||||||
experience, the full source code is available: |
|
||||||
:download:`github_commits.c`. To compile it (on Unix-like systems with |
|
||||||
gcc), use the following command:: |
|
||||||
|
|
||||||
gcc -o github_commits github_commits.c -ljansson -lcurl |
|
||||||
|
|
||||||
libcurl_ is used to communicate over the web, so it is required to |
|
||||||
compile the program. |
|
||||||
|
|
||||||
The command line syntax is:: |
|
||||||
|
|
||||||
github_commits USER REPOSITORY |
|
||||||
|
|
||||||
``USER`` is a GitHub user ID and ``REPOSITORY`` is the repository |
|
||||||
name. Please note that the GitHub API is rate limited, so if you run |
|
||||||
the program too many times within a short period of time, the sever |
|
||||||
starts to respond with an error. |
|
||||||
|
|
||||||
.. _GitHub: https://github.com/ |
|
||||||
.. _GitHub API: http://developer.github.com/ |
|
||||||
.. _libcurl: http://curl.haxx.se/ |
|
||||||
|
|
||||||
|
|
||||||
.. _tutorial-github-commits-api: |
|
||||||
|
|
||||||
The GitHub Repo Commits API |
|
||||||
=========================== |
|
||||||
|
|
||||||
The `GitHub Repo Commits API`_ is used by sending HTTP requests to |
|
||||||
URLs like ``https://api.github.com/repos/USER/REPOSITORY/commits``, |
|
||||||
where ``USER`` and ``REPOSITORY`` are the GitHub user ID and the name |
|
||||||
of the repository whose commits are to be listed, respectively. |
|
||||||
|
|
||||||
GitHub responds with a JSON array of the following form: |
|
||||||
|
|
||||||
.. code-block:: none |
|
||||||
|
|
||||||
[ |
|
||||||
{ |
|
||||||
"sha": "<the commit ID>", |
|
||||||
"commit": { |
|
||||||
"message": "<the commit message>", |
|
||||||
<more fields, not important to this tutorial...> |
|
||||||
}, |
|
||||||
<more fields...> |
|
||||||
}, |
|
||||||
{ |
|
||||||
"sha": "<the commit ID>", |
|
||||||
"commit": { |
|
||||||
"message": "<the commit message>", |
|
||||||
<more fields...> |
|
||||||
}, |
|
||||||
<more fields...> |
|
||||||
}, |
|
||||||
<more commits...> |
|
||||||
] |
|
||||||
|
|
||||||
In our program, the HTTP request is sent using the following |
|
||||||
function:: |
|
||||||
|
|
||||||
static char *request(const char *url); |
|
||||||
|
|
||||||
It takes the URL as a parameter, preforms a HTTP GET request, and |
|
||||||
returns a newly allocated string that contains the response body. If |
|
||||||
the request fails, an error message is printed to stderr and the |
|
||||||
return value is *NULL*. For full details, refer to :download:`the code |
|
||||||
<github_commits.c>`, as the actual implementation is not important |
|
||||||
here. |
|
||||||
|
|
||||||
.. _GitHub Repo Commits API: http://developer.github.com/v3/repos/commits/ |
|
||||||
|
|
||||||
.. _tutorial-the-program: |
|
||||||
|
|
||||||
The Program |
|
||||||
=========== |
|
||||||
|
|
||||||
First the includes:: |
|
||||||
|
|
||||||
#include <string.h> |
|
||||||
#include <jansson.h> |
|
||||||
|
|
||||||
Like all the programs using Jansson, we need to include |
|
||||||
:file:`jansson.h`. |
|
||||||
|
|
||||||
The following definitions are used to build the GitHub API request |
|
||||||
URL:: |
|
||||||
|
|
||||||
#define URL_FORMAT "https://api.github.com/repos/%s/%s/commits" |
|
||||||
#define URL_SIZE 256 |
|
||||||
|
|
||||||
The following function is used when formatting the result to find the |
|
||||||
first newline in the commit message:: |
|
||||||
|
|
||||||
/* Return the offset of the first newline in text or the length of |
|
||||||
text if there's no newline */ |
|
||||||
static int newline_offset(const char *text) |
|
||||||
{ |
|
||||||
const char *newline = strchr(text, '\n'); |
|
||||||
if(!newline) |
|
||||||
return strlen(text); |
|
||||||
else |
|
||||||
return (int)(newline - text); |
|
||||||
} |
|
||||||
|
|
||||||
The main function follows. In the beginning, we first declare a bunch |
|
||||||
of variables and check the command line parameters:: |
|
||||||
|
|
||||||
int main(int argc, char *argv[]) |
|
||||||
{ |
|
||||||
size_t i; |
|
||||||
char *text; |
|
||||||
char url[URL_SIZE]; |
|
||||||
|
|
||||||
json_t *root; |
|
||||||
json_error_t error; |
|
||||||
|
|
||||||
if(argc != 3) |
|
||||||
{ |
|
||||||
fprintf(stderr, "usage: %s USER REPOSITORY\n\n", argv[0]); |
|
||||||
fprintf(stderr, "List commits at USER's REPOSITORY.\n\n"); |
|
||||||
return 2; |
|
||||||
} |
|
||||||
|
|
||||||
Then we build the request URL using the user and repository names |
|
||||||
given as command line parameters:: |
|
||||||
|
|
||||||
snprintf(url, URL_SIZE, URL_FORMAT, argv[1], argv[2]); |
|
||||||
|
|
||||||
This uses the ``URL_SIZE`` and ``URL_FORMAT`` constants defined above. |
|
||||||
Now we're ready to actually request the JSON data over the web:: |
|
||||||
|
|
||||||
text = request(url); |
|
||||||
if(!text) |
|
||||||
return 1; |
|
||||||
|
|
||||||
If an error occurs, our function ``request`` prints the error and |
|
||||||
returns *NULL*, so it's enough to just return 1 from the main |
|
||||||
function. |
|
||||||
|
|
||||||
Next we'll call :func:`json_loads()` to decode the JSON text we got |
|
||||||
as a response:: |
|
||||||
|
|
||||||
root = json_loads(text, 0, &error); |
|
||||||
free(text); |
|
||||||
|
|
||||||
if(!root) |
|
||||||
{ |
|
||||||
fprintf(stderr, "error: on line %d: %s\n", error.line, error.text); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
|
|
||||||
We don't need the JSON text anymore, so we can free the ``text`` |
|
||||||
variable right after decoding it. If :func:`json_loads()` fails, it |
|
||||||
returns *NULL* and sets error information to the :type:`json_error_t` |
|
||||||
structure given as the second parameter. In this case, our program |
|
||||||
prints the error information out and returns 1 from the main function. |
|
||||||
|
|
||||||
Now we're ready to extract the data out of the decoded JSON response. |
|
||||||
The structure of the response JSON was explained in section |
|
||||||
:ref:`tutorial-github-commits-api`. |
|
||||||
|
|
||||||
We check that the returned value really is an array:: |
|
||||||
|
|
||||||
if(!json_is_array(root)) |
|
||||||
{ |
|
||||||
fprintf(stderr, "error: root is not an array\n"); |
|
||||||
json_decref(root); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
|
|
||||||
Then we proceed to loop over all the commits in the array:: |
|
||||||
|
|
||||||
for(i = 0; i < json_array_size(root); i++) |
|
||||||
{ |
|
||||||
json_t *data, *sha, *commit, *message; |
|
||||||
const char *message_text; |
|
||||||
|
|
||||||
data = json_array_get(root, i); |
|
||||||
if(!json_is_object(data)) |
|
||||||
{ |
|
||||||
fprintf(stderr, "error: commit data %d is not an object\n", i + 1); |
|
||||||
json_decref(root); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
... |
|
||||||
|
|
||||||
The function :func:`json_array_size()` returns the size of a JSON |
|
||||||
array. First, we again declare some variables and then extract the |
|
||||||
i'th element of the ``root`` array using :func:`json_array_get()`. |
|
||||||
We also check that the resulting value is a JSON object. |
|
||||||
|
|
||||||
Next we'll extract the commit ID (a hexadecimal SHA-1 sum), |
|
||||||
intermediate commit info object, and the commit message from that |
|
||||||
object. We also do proper type checks:: |
|
||||||
|
|
||||||
sha = json_object_get(data, "sha"); |
|
||||||
if(!json_is_string(sha)) |
|
||||||
{ |
|
||||||
fprintf(stderr, "error: commit %d: sha is not a string\n", i + 1); |
|
||||||
json_decref(root); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
|
|
||||||
commit = json_object_get(data, "commit"); |
|
||||||
if(!json_is_object(commit)) |
|
||||||
{ |
|
||||||
fprintf(stderr, "error: commit %d: commit is not an object\n", i + 1); |
|
||||||
json_decref(root); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
|
|
||||||
message = json_object_get(commit, "message"); |
|
||||||
if(!json_is_string(message)) |
|
||||||
{ |
|
||||||
fprintf(stderr, "error: commit %d: message is not a string\n", i + 1); |
|
||||||
json_decref(root); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
... |
|
||||||
|
|
||||||
And finally, we'll print the first 8 characters of the commit ID and |
|
||||||
the first line of the commit message. A C-style string is extracted |
|
||||||
from a JSON string using :func:`json_string_value()`:: |
|
||||||
|
|
||||||
message_text = json_string_value(message); |
|
||||||
printf("%.8s %.*s\n", |
|
||||||
json_string_value(id), |
|
||||||
newline_offset(message_text), |
|
||||||
message_text); |
|
||||||
} |
|
||||||
|
|
||||||
After sending the HTTP request, we decoded the JSON text using |
|
||||||
:func:`json_loads()`, remember? It returns a *new reference* to the |
|
||||||
JSON value it decodes. When we're finished with the value, we'll need |
|
||||||
to decrease the reference count using :func:`json_decref()`. This way |
|
||||||
Jansson can release the resources:: |
|
||||||
|
|
||||||
json_decref(root); |
|
||||||
return 0; |
|
||||||
|
|
||||||
For a detailed explanation of reference counting in Jansson, see |
|
||||||
:ref:`apiref-reference-count` in :ref:`apiref`. |
|
||||||
|
|
||||||
The program's ready, let's test it and view the latest commits in |
|
||||||
Jansson's repository:: |
|
||||||
|
|
||||||
$ ./github_commits akheron jansson |
|
||||||
1581f26a Merge branch '2.3' |
|
||||||
aabfd493 load: Change buffer_pos to be a size_t |
|
||||||
bd72efbd load: Avoid unexpected behaviour in macro expansion |
|
||||||
e8fd3e30 Document and tweak json_load_callback() |
|
||||||
873eddaf Merge pull request #60 from rogerz/contrib |
|
||||||
bd2c0c73 Ignore the binary test_load_callback |
|
||||||
17a51a4b Merge branch '2.3' |
|
||||||
09c39adc Add json_load_callback to the list of exported symbols |
|
||||||
cbb80baf Merge pull request #57 from rogerz/contrib |
|
||||||
040bd7b0 Add json_load_callback() |
|
||||||
2637faa4 Make test stripping locale independent |
|
||||||
<...> |
|
||||||
|
|
||||||
|
|
||||||
Conclusion |
|
||||||
========== |
|
||||||
|
|
||||||
In this tutorial, we implemented a program that fetches the latest |
|
||||||
commits of a GitHub repository using the GitHub Repo Commits API. |
|
||||||
Jansson was used to decode the JSON response and to extract the commit |
|
||||||
data. |
|
||||||
|
|
||||||
This tutorial only covered a small part of Jansson. For example, we |
|
||||||
did not create or manipulate JSON values at all. Proceed to |
|
||||||
:ref:`apiref` to explore all features of Jansson. |
|
@ -1,76 +0,0 @@ |
|||||||
.. highlight:: c |
|
||||||
|
|
||||||
****************** |
|
||||||
Upgrading from 1.x |
|
||||||
****************** |
|
||||||
|
|
||||||
This chapter lists the backwards incompatible changes introduced in |
|
||||||
Jansson 2.0, and the steps that are needed for upgrading your code. |
|
||||||
|
|
||||||
**The incompatibilities are not dramatic.** The biggest change is that |
|
||||||
all decoding functions now require and extra parameter. Most programs |
|
||||||
can be modified to work with 2.0 by adding a ``0`` as the second |
|
||||||
parameter to all calls of :func:`json_loads()`, :func:`json_loadf()` |
|
||||||
and :func:`json_load_file()`. |
|
||||||
|
|
||||||
|
|
||||||
Compatibility |
|
||||||
============= |
|
||||||
|
|
||||||
Jansson 2.0 is backwards incompatible with the Jansson 1.x releases. |
|
||||||
It is ABI incompatible, i.e. all programs dynamically linking to the |
|
||||||
Jansson library need to be recompiled. It's also API incompatible, |
|
||||||
i.e. the source code of programs using Jansson 1.x may need |
|
||||||
modifications to make them compile against Jansson 2.0. |
|
||||||
|
|
||||||
All the 2.x releases are guaranteed to be backwards compatible for |
|
||||||
both ABI and API, so no recompilation or source changes are needed |
|
||||||
when upgrading from 2.x to 2.y. |
|
||||||
|
|
||||||
|
|
||||||
List of Incompatible Changes |
|
||||||
============================ |
|
||||||
|
|
||||||
**Decoding flags** |
|
||||||
For future needs, a ``flags`` parameter was added as the second |
|
||||||
parameter to all decoding functions, i.e. :func:`json_loads()`, |
|
||||||
:func:`json_loadf()` and :func:`json_load_file()`. All calls to |
|
||||||
these functions need to be changed by adding a ``0`` as the second |
|
||||||
argument. For example:: |
|
||||||
|
|
||||||
/* old code */ |
|
||||||
json_loads(input, &error); |
|
||||||
|
|
||||||
/* new code */ |
|
||||||
json_loads(input, 0, &error); |
|
||||||
|
|
||||||
|
|
||||||
**Underlying type of JSON integers** |
|
||||||
The underlying C type of JSON integers has been changed from |
|
||||||
:type:`int` to the widest available signed integer type, i.e. |
|
||||||
:type:`long long` or :type:`long`, depending on whether |
|
||||||
:type:`long long` is supported on your system or not. This makes |
|
||||||
the whole 64-bit integer range available on most modern systems. |
|
||||||
|
|
||||||
``jansson.h`` has a typedef :type:`json_int_t` to the underlying |
|
||||||
integer type. :type:`int` should still be used in most cases when |
|
||||||
dealing with smallish JSON integers, as the compiler handles |
|
||||||
implicit type coercion. Only when the full 64-bit range is needed, |
|
||||||
:type:`json_int_t` should be explicitly used. |
|
||||||
|
|
||||||
|
|
||||||
**Maximum encoder indentation depth** |
|
||||||
The maximum argument of the ``JSON_INDENT()`` macro has been |
|
||||||
changed from 255 to 31, to free up bits from the ``flags`` |
|
||||||
parameter of :func:`json_dumps()`, :func:`json_dumpf()` and |
|
||||||
:func:`json_dump_file()`. If your code uses a bigger indentation |
|
||||||
than 31, it needs to be changed. |
|
||||||
|
|
||||||
|
|
||||||
**Unsigned integers in API functions** |
|
||||||
Version 2.0 unifies unsigned integer usage in the API. All uses of |
|
||||||
:type:`unsigned int` and :type:`unsigned long` have been replaced |
|
||||||
with :type:`size_t`. This includes flags, container sizes, etc. |
|
||||||
This should not require source code changes, as both |
|
||||||
:type:`unsigned int` and :type:`unsigned long` are usually |
|
||||||
compatible with :type:`size_t`. |
|
@ -1,39 +0,0 @@ |
|||||||
/*
|
|
||||||
* Copyright (c) 2010-2013 Petri Lehtinen <petri@digip.org> |
|
||||||
* |
|
||||||
* Jansson is free software; you can redistribute it and/or modify |
|
||||||
* it under the terms of the MIT license. See LICENSE for details. |
|
||||||
* |
|
||||||
* |
|
||||||
* This file specifies a part of the site-specific configuration for |
|
||||||
* Jansson, namely those things that affect the public API in |
|
||||||
* jansson.h. |
|
||||||
* |
|
||||||
* The configure script copies this file to jansson_config.h and |
|
||||||
* replaces @var@ substitutions by values that fit your system. If you |
|
||||||
* cannot run the configure script, you can do the value substitution |
|
||||||
* by hand. |
|
||||||
*/ |
|
||||||
|
|
||||||
#ifndef JANSSON_CONFIG_H |
|
||||||
#define JANSSON_CONFIG_H |
|
||||||
|
|
||||||
/* If your compiler supports the inline keyword in C, JSON_INLINE is
|
|
||||||
defined to `inline', otherwise empty. In C++, the inline is always |
|
||||||
supported. */ |
|
||||||
#ifdef __cplusplus |
|
||||||
#define JSON_INLINE inline |
|
||||||
#else |
|
||||||
#define JSON_INLINE __inline |
|
||||||
#endif |
|
||||||
|
|
||||||
/* If your compiler supports the `long long` type and the strtoll()
|
|
||||||
library function, JSON_INTEGER_IS_LONG_LONG is defined to 1, |
|
||||||
otherwise to 0. */ |
|
||||||
#define JSON_INTEGER_IS_LONG_LONG 1 |
|
||||||
|
|
||||||
/* If locale.h and localeconv() are available, define to 1,
|
|
||||||
otherwise to 0. */ |
|
||||||
#define JSON_HAVE_LOCALECONV 1 |
|
||||||
|
|
||||||
#endif |
|
Loading…
Reference in new issue