summaryrefslogtreecommitdiffstats
path: root/docs/gettingstarted/writingdocs
AgeCommit message (Collapse)AuthorFilesLines
2019-05-28docs: Add some packages for building the docsjdenisco1-0/+11
Change-Id: I7af427ba6378ddd8480a153a65ec11c578bab12e Signed-off-by: jdenisco <jdenisco@cisco.com>
2019-05-16docs: Update sphinx, requirements, support markdown tablesjdenisco1-0/+10
Change-Id: Ie7c546f5720b10fe5423397204e1ab5c22d7a2ba Signed-off-by: jdenisco <jdenisco@cisco.com>
2018-09-24Add the sphinx docs build optionsjdenisco1-8/+12
Change-Id: If7ac5b41ca4ac602a100b616b37d07f658fd6a90 Signed-off-by: jdenisco <jdenisco@cisco.com>
2018-08-14DOCS: Moved multiarch and build system, Incorprated Scott's changesJohn DeNisco1-1/+1
Change-Id: I5a57846db2d4faac1aa24db4629b612657f59afb Signed-off-by: John DeNisco <jdenisco@cisco.com>
2018-08-13DOCS: Cleanup Getting StartedJohn DeNisco6-747/+23
Change-Id: I4766773779f8d5c30a24bfed48090d7305c80ec5 Signed-off-by: John DeNisco <jdenisco@cisco.com>
2018-08-09DOCS: General cleanup (did not move any sections)andrew3-16/+19
Change-Id: I67cc42769661c10d2793f8c6cdb3b232b803d145 Signed-off-by: andrew <andrew.olechtchouk@gmail.com>
2018-08-09DOCS: modified writing docs sectionjavierfernandezvalles1-1/+1
Change-Id: Ic3ec16dba1a6374785f25f622b2cdc9b6415a13b Signed-off-by: javierfernandezvalles <JaviervallesF@gmail.com>
2018-08-07docs: Cleaned up a little removed instructions for mac.andrew1-22/+89
docs: Updated section on using git-review Change-Id: I180f67e3478b57b1de03df95fc67a0cfdd44dfb5 Signed-off-by: andrew <andrew.olechtchouk@gmail.com>
2018-08-03Added missing fileJohn DeNisco2-5/+1
docs: Incorporate Javier's progressive VPP tutorial Change-Id: Iecee041039c7ed81713bc0530fc536e989c71497 Signed-off-by: John DeNisco <jdenisco@cisco.com>
2018-08-03docs: Incororate Scott's overall reviewJohn DeNisco1-3/+9
Change-Id: Ic70a62e17891fa9291a5274400ae89f1d6194b6e Signed-off-by: John DeNisco <jdenisco@cisco.com>
2018-07-27Fix .gitignore so docs/Makefile is not ignored. Add README and Makefile. Fis ↵John DeNisco1-11/+11
gitreview. Change-Id: I3d664d9c881ce127a09b9d68c1181a7098a39074 Signed-off-by: John DeNisco <jdenisco@cisco.com>
2018-07-26Initial commit of Sphinx docsJohn DeNisco20-0/+1260
Change-Id: I9fca8fb98502dffc2555f9de7f507b6f006e0e77 Signed-off-by: John DeNisco <jdenisco@cisco.com>
ighlight .sc { color: #e6db74 } /* Literal.String.Char */ .highlight .dl { color: #e6db74 } /* Literal.String.Delimiter */ .highlight .sd { color: #e6db74 } /* Literal.String.Doc */ .highlight .s2 { color: #e6db74 } /* Literal.String.Double */ .highlight .se { color: #ae81ff } /* Literal.String.Escape */ .highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */ .highlight .si { color: #e6db74 } /* Literal.String.Interpol */ .highlight .sx { color: #e6db74 } /* Literal.String.Other */ .highlight .sr { color: #e6db74 } /* Literal.String.Regex */ .highlight .s1 { color: #e6db74 } /* Literal.String.Single */ .highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ .highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #a6e22e } /* Name.Function.Magic */ .highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ .highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ .highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ .highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */ .highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ } @media (prefers-color-scheme: light) { .highlight .hll { background-color: #ffffcc } .highlight .c { color: #888888 } /* Comment */ .highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ .highlight .k { color: #008800; font-weight: bold } /* Keyword */ .highlight .ch { color: #888888 } /* Comment.Hashbang */ .highlight .cm { color: #888888 } /* Comment.Multiline */ .highlight .cp { color: #cc0000; font-weight: bold } /* Comment.Preproc */ .highlight .cpf { color: #888888 } /* Comment.PreprocFile */ .highlight .c1 { color: #888888 } /* Comment.Single */ .highlight .cs { color: #cc0000; font-weight: bold; background-color: #fff0f0 } /* Comment.Special */ .highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ .highlight .ge { font-style: italic } /* Generic.Emph */ .highlight .gr { color: #aa0000 } /* Generic.Error */ .highlight .gh { color: #333333 } /* Generic.Heading */ .highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ .highlight .go { color: #888888 } /* Generic.Output */ .highlight .gp { color: #555555 } /* Generic.Prompt */ .highlight .gs { font-weight: bold } /* Generic.Strong */ .highlight .gu { color: #666666 } /* Generic.Subheading */ .highlight .gt { color: #aa0000 } /* Generic.Traceback */ .highlight .kc { color: #008800; font-weight: bold } /* Keyword.Constant */ .highlight .kd { color: #008800; font-weight: bold } /* Keyword.Declaration */ .highlight .kn { color: #008800; font-weight: bold } /* Keyword.Namespace */ .highlight .kp { color: #008800 } /* Keyword.Pseudo */ .highlight .kr { color: #008800; font-weight: bold } /* Keyword.Reserved */ .highlight .kt { color: #888888; font-weight: bold } /* Keyword.Type */ .highlight .m { color: #0000DD; font-weight: bold } /* Literal.Number */ .highlight .s { color: #dd2200; background-color: #fff0f0 } /* Literal.String */ .highlight .na { color: #336699 } /* Name.Attribute */ .highlight .nb { color: #003388 } /* Name.Builtin */ .highlight .nc { color: #bb0066; font-weight: bold } /* Name.Class */ .highlight .no { color: #003366; font-weight: bold } /* Name.Constant */ .highlight .nd { color: #555555 } /* Name.Decorator */ .highlight .ne { color: #bb0066; font-weight: bold } /* Name.Exception */ .highlight .nf { color: #0066bb; font-weight: bold } /* Name.Function */ .highlight .nl { color: #336699; font-style: italic } /* Name.Label */ .highlight .nn { color: #bb0066; font-weight: bold } /* Name.Namespace */ .highlight .py { color: #336699; font-weight: bold } /* Name.Property */ .highlight .nt { color: #bb0066; font-weight: bold } /* Name.Tag */ .highlight .nv { color: #336699 } /* Name.Variable */ .highlight .ow { color: #008800 } /* Operator.Word */ .highlight .w { color: #bbbbbb } /* Text.Whitespace */ .highlight .mb { color: #0000DD; font-weight: bold } /* Literal.Number.Bin */ .highlight .mf { color: #0000DD; font-weight: bold } /* Literal.Number.Float */ .highlight .mh { color: #0000DD; font-weight: bold } /* Literal.Number.Hex */ .highlight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */ }
#!/usr/bin/env python3

import argparse
import os
import sys
import logging
from vapi_c_gen import CField, CEnum, CStruct, CSimpleType, CStructType,\
    CMessage, json_to_c_header_name, CAlias
from vapi_json_parser import JsonParser


class CppField(CField):
    pass


class CppStruct(CStruct):
    pass


class CppEnum(CEnum):
    pass


class CppAlias(CAlias):
    pass


class CppSimpleType (CSimpleType):
    pass


class CppStructType (CStructType, CppStruct):
    pass


class CppMessage (CMessage):
    def get_swap_to_be_template_instantiation(self):
        return "\n".join([
            "template <> inline void vapi_swap_to_be<%s>(%s *msg)" %
            (self.get_c_name(), self.get_c_name()),
            "{",
            "  %s(msg);" % self.get_swap_to_be_func_name(),
            "}",
        ])

    def get_swap_to_host_template_instantiation(self):
        return "\n".join([
            "template <> inline void vapi_swap_to_host<%s>(%s *msg)" %
            (self.get_c_name(), self.get_c_name()),
            "{",
            "  %s(msg);" % self.get_swap_to_host_func_name(),
            "}",
        ])

    def get_alloc_template_instantiation(self):
        return "\n".join([
            "template <> inline %s* vapi_alloc<%s%s>"
            "(Connection &con%s)" %
            (self.get_c_name(), self.get_c_name(),
                ", size_t" * len(self.get_alloc_vla_param_names()),
                "".join([", size_t %s" % n for n in
                         self.get_alloc_vla_param_names()])
             ),
            "{",
            "  %s* result = %s(con.vapi_ctx%s);" %
            (self.get_c_name(), self.get_alloc_func_name(),
                "".join([", %s" % n
                         for n in self.get_alloc_vla_param_names()])),
            "#if VAPI_CPP_DEBUG_LEAKS",
            "  con.on_shm_data_alloc(result);",
            "#endif",
            "  return result;",
            "}",
        ])

    def get_cpp_name(self):
        return "%s%s" % (self.name[0].upper(), self.name[1:])

    def get_req_template_name(self):
        if self.reply_is_stream:
            template = "Dump"
        else:
            template = "Request"

        return "%s<%s, %s%s>" % (
            template,
            self.get_c_name(),
            self.reply.get_c_name(),
            "".join([", size_t"] * len(self.get_alloc_vla_param_names()))
        )

    def get_req_template_instantiation(self):
        return "template class %s;" % self.get_req_template_name()

    def get_type_alias(self):
        return "using %s = %s;" % (
            self.get_cpp_name(), self.get_req_template_name())

    def get_reply_template_name(self):
        return "Msg<%s>" % (self.get_c_name())

    def get_reply_type_alias(self):
        return "using %s = %s;" % (
            self.get_cpp_name(), self.get_reply_template_name())

    def get_msg_class_instantiation(self):
        return "template class Msg<%s>;" % self.get_c_name()

    def get_get_msg_id_t_instantiation(self):
        return "\n".join([
            ("template <> inline vapi_msg_id_t vapi_get_msg_id_t<%s>()"
                % self.get_c_name()),
            "{",
            "  return ::%s; " % self.get_msg_id_name(),
            "}",
            "",
            ("template <> inline vapi_msg_id_t "
             "vapi_get_msg_id_t<Msg<%s>>()" % self.get_c_name()),
            "{",
            "  return ::%s; " % self.get_msg_id_name(),
            "}",
        ])

    def get_cpp_constructor(self):
        return '\n'.join([
            ('static void __attribute__((constructor)) '
             '__vapi_cpp_constructor_%s()'
             % self.name),
            '{',
            ('  vapi::vapi_msg_set_msg_id<%s>(%s);' % (
                self.get_c_name(), self.get_msg_id_name())),
            '}',
        ])


def gen_json_header(parser, logger, j, io, gen_h_prefix, add_debug_comments):
    logger.info("Generating header `%s'" % io.name)
    orig_stdout = sys.stdout
    sys.stdout = io
    d, f = os.path.split(j)
    include_guard = "__included_hpp_%s" % (
        f.replace(".", "_").replace("/", "_").replace("-", "_"))
    print("#ifndef %s" % include_guard)
    print("#define %s" % include_guard)
    print("")
    print("#include <vapi/vapi.hpp>")
    print("#include <%s%s>" % (gen_h_prefix, json_to_c_header_name(f)))
    print("")
    print("namespace vapi {")
    print("")
    for m in parser.messages_by_json[j].values():
        # utility functions need to go first, otherwise internal instantiation
        # causes headaches ...
        if add_debug_comments:
            print("/* m.get_swap_to_be_template_instantiation() */")
        print("%s" % m.get_swap_to_be_template_instantiation())
        print("")
        if add_debug_comments:
            print("/* m.get_swap_to_host_template_instantiation() */")
        print("%s" % m.get_swap_to_host_template_instantiation())
        print("")
        if add_debug_comments:
            print("/* m.get_get_msg_id_t_instantiation() */")
        print("%s" % m.get_get_msg_id_t_instantiation())
        print("")
        if add_debug_comments:
            print("/* m.get_cpp_constructor() */")
        print("%s" % m.get_cpp_constructor())
        print("")
        if not m.is_reply and not m.is_event:
            if add_debug_comments:
                print("/* m.get_alloc_template_instantiation() */")
            print("%s" % m.get_alloc_template_instantiation())
            print("")
        if add_debug_comments:
            print("/* m.get_msg_class_instantiation() */")
        print("%s" % m.get_msg_class_instantiation())
        print("")
        if m.is_reply or m.is_event:
            if add_debug_comments:
                print("/* m.get_reply_type_alias() */")
            print("%s" % m.get_reply_type_alias())
            continue
        if add_debug_comments:
            print("/* m.get_req_template_instantiation() */")
        print("%s" % m.get_req_template_instantiation())
        print("")
        if add_debug_comments:
            print("/* m.get_type_alias() */")
        print("%s" % m.get_type_alias())
        print("")
    print("}")  # namespace vapi

    print("#endif")
    sys.stdout = orig_stdout


def json_to_cpp_header_name(json_name):
    if json_name.endswith(".json"):
        return "%s.vapi.hpp" % os.path.splitext(json_name)[0]
    raise Exception("Unexpected json name `%s'!" % json_name)


def gen_cpp_headers(parser, logger, prefix, gen_h_prefix, remove_path,
                    add_debug_comments=False):
    if prefix == "" or prefix is None:
        prefix = ""
    else:
        prefix = "%s/" % prefix
    if gen_h_prefix is None:
        gen_h_prefix = ""
    else:
        gen_h_prefix = "%s/" % gen_h_prefix
    for j in parser.json_files:
        if remove_path:
            d, f = os.path.split(j)
        else:
            f = j
        with open('%s%s' % (prefix, json_to_cpp_header_name(f)), "w") as io:
            gen_json_header(parser, logger, j, io,
                            gen_h_prefix, add_debug_comments)


if __name__ == '__main__':
    try:
        verbose = int(os.getenv("V", 0))
    except:
        verbose = 0

    if verbose >= 2:
        log_level = 10
    elif verbose == 1:
        log_level = 20
    else:
        log_level = 40

    logging.basicConfig(stream=sys.stdout, level=log_level)
    logger = logging.getLogger("VAPI CPP GEN")
    logger.setLevel(log_level)

    argparser = argparse.ArgumentParser(description="VPP C++ API generator")
    argparser.add_argument('files', metavar='api-file', action='append',
                           type=str, help='json api file'
                           '(may be specified multiple times)')
    argparser.add_argument('--prefix', action='store', default=None,
                           help='path prefix')
    argparser.add_argument('--gen-h-prefix', action='store', default=None,
                           help='generated C header prefix')
    argparser.add_argument('--remove-path', action='store_true',
                           help='remove path from filename')
    args = argparser.parse_args()

    jsonparser = JsonParser(logger, args.files,
                            simple_type_class=CppSimpleType,
                            struct_type_class=CppStructType,
                            field_class=CppField,
                            enum_class=CppEnum,
                            message_class=CppMessage,
                            alias_class=CppAlias)

    gen_cpp_headers(jsonparser, logger, args.prefix, args.gen_h_prefix,
                    args.remove_path)

    for e in jsonparser.exceptions:
        logger.warning(e)