aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Luke <chrisy@flirble.org>2016-05-14 12:17:12 -0400
committerKeith Burns <alagalah@gmail.com>2016-05-15 13:22:54 +0000
commit75a37b372efc2b4a324aa38b53487b8168358a63 (patch)
tree723b47db3ecf25492cad6076efc8a8f5e1162130
parent7e55d364fd88bb462c7211209f5cbb5bbae3a68c (diff)
VPP-62 Add a doxy filter to enable vpe.api doc
This makes Doxygen think the API definitions are structs which is close enough to be able to document the API methods. It also has logic to create an indexed API page but that's disabled for now because it duplicates the "brief" text twice in the struct doc. Fixes a minor line numbering issue in filter_c.py. Change-Id: If380160b73e7c10d999b35a76f55d0e27cbc91cc Signed-off-by: Chris Luke <chrisy@flirble.org>
-rw-r--r--doxygen/doxygen.cfg8
-rwxr-xr-xdoxygen/filter_api.py45
-rwxr-xr-xdoxygen/filter_c.py19
3 files changed, 67 insertions, 5 deletions
diff --git a/doxygen/doxygen.cfg b/doxygen/doxygen.cfg
index 6d6bb6ccf21..ec4312c9fe7 100644
--- a/doxygen/doxygen.cfg
+++ b/doxygen/doxygen.cfg
@@ -281,7 +281,7 @@ OPTIMIZE_OUTPUT_VHDL = NO
# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
# the files are not read by doxygen.
-EXTENSION_MAPPING = def=C
+EXTENSION_MAPPING = def=C api=C
# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
# according to the Markdown format, which allows for more readable
@@ -796,7 +796,7 @@ INPUT_ENCODING = UTF-8
# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl,
# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js.
-FILE_PATTERNS = *.md *.c *.h *.def *.inc *.S *.dox
+FILE_PATTERNS = *.md *.c *.h *.def *.inc *.S *.dox *.api
# The RECURSIVE tag can be used to specify whether or not subdirectories should
# be searched for input files as well.
@@ -898,7 +898,9 @@ INPUT_FILTER =
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.
-FILTER_PATTERNS = *.c=$(ROOT)/doxygen/filter_c.py
+FILTER_PATTERNS = \
+ *.c=$(ROOT)/doxygen/filter_c.py \
+ *.api=$(ROOT)/doxygen/filter_api.py
# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
# INPUT_FILTER) will also be used to filter the input files that are used for
diff --git a/doxygen/filter_api.py b/doxygen/filter_api.py
new file mode 100755
index 00000000000..3e2aaaec290
--- /dev/null
+++ b/doxygen/filter_api.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python
+# Copyright (c) 2016 Comcast Cable Communications Management, LLC.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Filter for vpe.api to make it Doxygenish.
+
+import sys, re
+
+if len(sys.argv) < 2:
+ sys.stderr.write("Usage: %s <filename>\n" % (sys.argv[0]))
+ sys.exit(1)
+
+patterns = [
+ # Search for "define" blocks and treat them as structs
+ ( re.compile(r"^.*(manual_.[^\s]+\s+)?define\s+(?P<name>[^\s]+)"), r"typedef struct vl_api_\g<name>_t"),
+
+ # For every "brief" statement at the start of a comment block, add an
+ # xref with whatever is on the same line. This gives us an index page
+ # with all the API methods in one place.
+ # XXX Commented out for now; works but duplicates the brief text in the
+ # struct documentation
+ #( re.compile(r"/\*\*\s*(?P<b>[\\@]brief)\s+(?P<c>.+)(\*/)$"), r'/** @xrefitem api "" "VPP API" \g<c> \g<b> \g<c>'), # capture inline comment close
+ #( re.compile(r"/\*\*\s*(?P<b>[\\@]brief)\s+(?P<c>.+)$"), r'/** @xrefitem api "" "VPP API" \g<c> \g<b> \g<c>'),
+
+ # Since structs don't have params, replace @param with @tparam
+ ( re.compile("[\\@]param\\b"), "@tparam"),
+]
+
+with open(sys.argv[1]) as fd:
+ for line in fd:
+ str = line[:-1] # strip \n
+ for p in patterns:
+ str = p[0].sub(p[1], str)
+ sys.stdout.write(str+"\n")
diff --git a/doxygen/filter_c.py b/doxygen/filter_c.py
index 5a812a55436..db1681c9450 100755
--- a/doxygen/filter_c.py
+++ b/doxygen/filter_c.py
@@ -1,4 +1,19 @@
#!/usr/bin/env python
+# Copyright (c) 2016 Comcast Cable Communications Management, LLC.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Filter for .c files to make various preprocessor tricks Doxygenish
import sys, re
@@ -31,7 +46,7 @@ patterns = [
with open(sys.argv[1]) as fd:
for line in fd:
- str = line
+ str = line[:-1] # filter \n
for p in patterns:
str = p[0].sub(p[1], str)
- sys.stdout.write(str)
+ sys.stdout.write(str+"\n")
l.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 */ }
/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef __included_ssvm_h__
#define __included_ssvm_h__

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <signal.h>
#include <pthread.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <string.h>
#include <vppinfra/clib.h>
#include <vppinfra/vec.h>
#include <vppinfra/hash.h>
#include <vppinfra/bitmap.h>
#include <vppinfra/fifo.h>
#include <vppinfra/time.h>
#include <vppinfra/mheap.h>
#include <vppinfra/heap.h>
#include <vppinfra/pool.h>
#include <vppinfra/format.h>
#include <vppinfra/linux/syscall.h>

#ifndef MMAP_PAGESIZE
#define MMAP_PAGESIZE (clib_mem_get_page_size())
#endif

#define SSVM_N_OPAQUE 7

typedef struct
{
  /* Spin-lock */
  volatile u32 lock;
  volatile u32 owner_pid;
  int recursion_count;
  u32 tag;			/* for debugging */

  /* The allocation arena */
  void *heap;

  /* Segment must be mapped at this address, or no supper */
  u64 ssvm_va;
  /* The actual mmap size */
  u64 ssvm_size;
  u32 master_pid;
  u32 slave_pid;
  u8 *name;
  void *opaque[SSVM_N_OPAQUE];

  /* Set when the master application thinks it's time to make the donuts */
  volatile u32 ready;

  /* Needed to make unique MAC addresses, etc. */
  u32 master_index;
} ssvm_shared_header_t;

typedef struct
{
  ssvm_shared_header_t *sh;
  u64 ssvm_size;
  u32 my_pid;
  u8 *name;
  uword requested_va;
  int i_am_master;

  /* Needed by memfd segments */
  int fd;
} ssvm_private_t;

always_inline void
ssvm_lock (ssvm_shared_header_t * h, u32 my_pid, u32 tag)
{
  if (h->owner_pid == my_pid)
    {
      h->recursion_count++;
      return;
    }

  while (__sync_lock_test_and_set (&h->lock, 1))
    ;

  h->owner_pid = my_pid;
  h->recursion_count = 1;
  h->tag = tag;
}

always_inline void
ssvm_lock_non_recursive (ssvm_shared_header_t * h, u32 tag)
{
  while (__sync_lock_test_and_set (&h->lock, 1))
    ;

  h->tag = tag;
}

always_inline void
ssvm_unlock (ssvm_shared_header_t * h)
{
  if (--h->recursion_count == 0)
    {
      h->owner_pid = 0;
      h->tag = 0;
      CLIB_MEMORY_BARRIER ();
      h->lock = 0;
    }
}

always_inline void
ssvm_unlock_non_recursive (ssvm_shared_header_t * h)
{
  h->tag = 0;
  CLIB_MEMORY_BARRIER ();
  h->lock = 0;
}

static inline void *
ssvm_push_heap (ssvm_shared_header_t * sh)
{
  u8 *oldheap;
  oldheap = clib_mem_set_heap (sh->heap);
  return ((void *) oldheap);
}

static inline void
ssvm_pop_heap (void *oldheap)
{
  clib_mem_set_heap (oldheap);
}

#define foreach_ssvm_api_error                  \
_(NO_NAME, "No shared segment name", -100)      \
_(NO_SIZE, "Size not set (master)", -101)       \
_(CREATE_FAILURE, "Create failed", -102)        \
_(SET_SIZE, "Set size failed", -103)		\
_(MMAP, "mmap failed", -104)			\
_(SLAVE_TIMEOUT, "Slave map timeout", -105)

typedef enum
{
#define _(n,s,c) SSVM_API_ERROR_##n = c,
  foreach_ssvm_api_error
#undef _
} ssvm_api_error_enum_t;

#define SSVM_API_ERROR_NO_NAME	(-10)

int ssvm_master_init (ssvm_private_t * ssvm, u32 master_index);
int ssvm_slave_init (ssvm_private_t * ssvm, int timeout_in_seconds);
void ssvm_delete (ssvm_private_t * ssvm);

int ssvm_master_init_memfd (ssvm_private_t * memfd, u32 master_index);
int ssvm_slave_init_memfd (ssvm_private_t * memfd);
void ssvm_delete_memfd (ssvm_private_t * memfd);

#endif /* __included_ssvm_h__ */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */