]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Doc: Programmer documentation formatting for new website
authorMaria Matejka <mq@ucw.cz>
Tue, 27 Jan 2026 10:28:25 +0000 (11:28 +0100)
committerMaria Matejka <mq@ucw.cz>
Tue, 7 Apr 2026 09:50:51 +0000 (11:50 +0200)
doc/kernel-doc
doc/prog-intro.sgml
lib/resource.sgml
nest/proto.sgml
proto/rpki/rpki.c
sysdep/sysdep.sgml
tools/doc-template.html
tools/linuxdoc.lua
tools/progdoc

index e3272fcf5ef0a29d392834d7bb82029fb3bf6468..a65f170c7c3927fc07bf4761c65fbad42dc65ae9 100755 (executable)
@@ -82,7 +82,7 @@
 # '|code|' - literal string
 
 # match expressions used to find embedded type information
-$type_constant = "\\\%(\\w+)";
+$type_constant = "(?<![|])\\\%(\\w+)";
 $type_func = "(\\w+\\(\\))";
 $type_param = "\\\@(\\w+)";
 $type_struct = "\\\&(\\w+)";
@@ -205,7 +205,7 @@ while ($ARGV[0] =~ m/^-(.*)/) {
 # generate a sequence of code that will splice in highlighting information
 # using the s// operator.
 $dohighlight = "";
-foreach $pattern (keys %highlights) {
+foreach $pattern (sort keys %highlights) {
 #    print "scanning pattern $pattern ($highlights{$pattern})\n";
     $dohighlight .=  "\$contents =~ s:$pattern:$highlights{$pattern}:gs;\n";
 }
@@ -580,7 +580,9 @@ sub output_intro_bird {
     # print out each section
     $lineprefix="   ";
     foreach $section (@{$args{'sectionlist'}}) {
-       print "<sect>$section\n<p>\n";
+       my $lbl = lc $section;
+       $lbl =~ tr/ /-/;
+       print "<sect>$section\n<label id=\"$lbl\"><p>\n";
        output_highlight($args{'sections'}{$section});
     }
 
index a8eabe53a6e6715aa5d74ad17eab825928bdeae4..ab67d3644f51c78c3e6cbb213a4bf5e8a1126666 100644 (file)
@@ -1,6 +1,8 @@
 <chapt>BIRD Design
+<label id="bird-design">
 
 <sect>Introduction
+<label id="bird-design-introduction">
 
 <p>This document describes the internal workings of BIRD, its architecture,
 design decisions and rationale behind them. It also contains documentation on
@@ -18,6 +20,7 @@ the most important stuff and leaving the boring technical details better explain
 by the program source itself together with comments contained therein.
 
 <sect>Design goals
+<label id="bird-design-goals">
 
 <p>When planning the architecture of BIRD, we've taken a close look at the other existing routing
 daemons and also at some of the operating systems used on dedicated routers, gathered all important
@@ -83,6 +86,7 @@ events or timers to make the CPU available for other tasks as well.
 </itemize>
 
 <sect>Architecture
+<label id="bird-design-architecture">
 
 <p>The requirements set above have lead to a simple modular architecture containing
 the following types of modules:
@@ -120,6 +124,7 @@ interface to the CLI.
 </descrip>
 
 <sect>Implementation
+<label id="bird-design-implementation">
 
 <p>BIRD has been written in GNU C. We've considered using C++, but we've
 preferred the simplicity and straightforward nature of C which gives us fine
index 48974f0a26be5cc483c67760e546a71224bc737b..bbc3111a8d93f7024959f863def2320ba364b67a 100644 (file)
@@ -5,8 +5,10 @@
 -->
 
 <chapt>Resources
+<label id="resources">
 
 <sect>Introduction
+<label id="resources-introduction">
 
 <p>Most large software projects implemented in classical procedural
 programming languages usually end up with lots of code taking care
index 53da78b8d516f740d0f2aacb5c471f1b7517d782..951705b74b3acdd0613845f1fac5f2113506d3cf 100644 (file)
@@ -5,8 +5,10 @@
 -->
 
 <sect>Routing protocols
+<label id="routing-protocols">
 
 <sect1>Introduction
+<label id="routing-protocols-introduction">
 
 <p>The routing protocols are the bird's heart and a fine amount of code
 is dedicated to their management and for providing support functions to them.
@@ -42,6 +44,7 @@ configuration of protocols, please refer to the configuration chapter and also
 to the description of the <func/proto_commit/ function.
 
 <sect1>Protocol states
+<label id="routing-protocols-states">
 
 <p>As startup and shutdown of each protocol are complex processes which can be affected
 by lots of external events (user's actions, reconfigurations, behavior of neighboring routers etc.),
@@ -70,5 +73,6 @@ its state by calling the <func/proto_notify_state/ function.
 <p>At any time, the core code can ask the protocol to shut itself down by calling its stop() hook.
 
 <sect1>Functions of the protocol module
+<label id="routing-protocols-functions">
 
 <p>The protocol module provides the following functions:
index 0d1c48f572485ddabe53d08bae46642f9f9f14eb..ab62822f013e36204aaece3042c2be9e459f272e 100644 (file)
@@ -22,7 +22,7 @@
  * transport. Transport is a way how to wrap a communication with a cache
  * server. There is supported an unprotected TCP transport and an encrypted
  * SSHv2 transport. The SSH transport requires LibSSH library. LibSSH is
- * loading dynamically using |dlopen()| function. SSH support is integrated in
+ * loading dynamically using dlopen() function. SSH support is integrated in
  * |sysdep/unix/io.c|. Each transport must implement an initialization
  * function, an open function and a socket identification function. That's all.
  *
  * |tcp_transport.c| and |ssh_transport.c| from RTRlib.
  *
  * A RPKI-RTR connection is described by a structure &rpki_cache. The main
- * logic is located in |rpki_cache_change_state()| function. There is a state
+ * logic is located in rpki_cache_change_state() function. There is a state
  * machine. The standard starting state flow looks like |Down| ~> |Connecting|
  * ~> |Sync-Start| ~> |Sync-Running| ~> |Established| and then the last three
  * states are periodically repeated.
  *
  * |Connecting| state establishes the transport connection. The state from a
- * call |rpki_cache_change_state(CONNECTING)| to a call |rpki_connected_hook()|
+ * call rpki_cache_change_state(CONNECTING) to a call rpki_connected_hook()
  *
  * |Sync-Start| state starts with sending |Reset Query| or |Serial Query| and
- * then waits for |Cache Response|. The state from |rpki_connected_hook()| to
- * |rpki_handle_cache_response_pdu()|
+ * then waits for |Cache Response|. The state from rpki_connected_hook() to
+ * rpki_handle_cache_response_pdu()
  *
  * During |Sync-Running| BIRD receives data with IPv4/IPv6 Prefixes from cache
- * server. The state starts from |rpki_handle_cache_response_pdu()| and ends
- * in |rpki_handle_end_of_data_pdu()|.
+ * server. The state starts from rpki_handle_cache_response_pdu() and ends
+ * in rpki_handle_end_of_data_pdu().
  *
  * |Established| state means that BIRD has synced all data with cache server.
  * Schedules a refresh timer event that invokes |Sync-Start|. Schedules Expire
@@ -61,8 +61,8 @@
  *
  * The RPKI-RTR protocol (RFC 6810 bis) defines configurable refresh, retry and
  * expire intervals. For maintaining a connection are used timer events that
- * are scheduled by |rpki_schedule_next_refresh()|,
- * |rpki_schedule_next_retry()| and |rpki_schedule_next_expire()| functions.
+ * are scheduled by rpki_schedule_next_refresh(),
+ * rpki_schedule_next_retry() and rpki_schedule_next_expire() functions.
  *
  * A Refresh timer event performs a sync of |Established| connection. So it
  * shifts state to |Sync-Start|. If at the beginning of second call of a
index b9ccb639297a2dbb0475372468772e3b6a884319..16c41aa825b57fdf41f48aff4c1e9885ae3b742f 100644 (file)
@@ -5,15 +5,17 @@
 -->
 
 <chapt>System dependent parts
+<label id="sysdep">
 
 <sect>Introduction
+<label id="sysdep-intro">
 
 <p>We've tried to make BIRD as portable as possible, but unfortunately
 communication with the network stack differs from one OS to another,
 so we need at least some OS specific code. The good news is that this
 code is isolated in a small set of modules:
 
-<descrip>
+<p><descrip>
 <tagp><tt/config.h/</tagp> is a header file with configuration information,
 definition of the standard set of types and so on.
 <tagp/Startup module/ controls BIRD startup. Common for a family of OS's (e.g.,
index 25f63c5259b62623374abd6950e591e4e59b9d04..6ac39b24fa14cc5429cfffdf86a7554cb8b260a8 100644 (file)
@@ -3,6 +3,12 @@
 {%- set template_part = "header" %}
 {%- set authors = [ $for(author-meta)$ "$author-meta$", $endfor$ ] %}
 {%- set meta_additional = { "author": authors, } %}
+{%- set ns = namespace(progdoc=False) %}
+{%- for v in releases -%}
+  {%- if "$bird_version$" == v.version -%}
+    {%- set ns.progdoc = ("progdoc" in v) -%}
+  {%- endif -%}
+{%- endfor -%}
 {%- include "main.html.j2" %}
 <!--<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>-->
       <section class="bg-light bird-documentation">
            <div class="col-12 col-xl-6 col-lg-7">
              <h1 class="title">{{ title }}</h1>
              <div class="version-info pb-20 mb-20 border-bottom border-primary">
-               <h4>Version $bird_version$ | <a href="/download/bird-doc-$bird_version$.tar.gz">TGZ</a></h4>
+               <h4>Version $bird_version$ | <a href="/download/bird-doc-$bird_version$.tar.gz">TGZ</a>{% if ns.progdoc %} | <a href="/doc/prog-$bird_version$.html">ProgDoc</a>{% endif %}</h4>
                Available versions:
                {% for v in releases | reverse -%}
                  {% if (v.type == 'current') or 'show_doc' in v %}
-                   <a href="
-                     {%- if "$bird_version$" == v.version -%}
-                     #
-                     {%- else -%}
-                     /doc/bird-{{ v.version }}.html
-                     {%- endif -%}
-                     " style="{% if v.type == 'current' %}font-weight: bold;{% endif %}">
+                   <a href="/doc/bird-{{ v.version }}.html" style="{% if v.type == 'current' %}font-weight: bold;{% endif %}">
                      {{- v.version -}}
                    </a>
                    {%- if not loop.last %} | {% endif -%}
index 4976d8800726cbc8fc1564d98a06960076e3beaf..2e2962b71da920cba443cffa8f40ec8944133c8c 100644 (file)
@@ -26,6 +26,8 @@ local entitytab = {
   tilde = "~";
   amp = "&";
   verbar = "|";
+  latex = "LaTeX";
+  tex = "TeX";
 }
 local entity = P"&" * C(P(1 - S"&;")^1) * P";" / function (t)
   local e = entitytab[t]
@@ -92,7 +94,7 @@ G = P{ "Pandoc",
   end;
 
   BookInside = V"Comment" + V"BookIgnored" + V"Title" + V"Author" + V"Date" + V"DocumentID" + V"Abstract" + V"Chapter" + blankchar + V"ParseFail";
-  BookIgnored = P"<toc>";
+  BookIgnored = P"<toc>" + P"<progdoc>";
   Book = P"<book>" * Ct(V"BookInside"^1) * P"</book>" / mergetables;
 
   Title = P"<title>" * inelement / function (t)
@@ -146,6 +148,7 @@ G = P{ "Pandoc",
     })
   end;
   Sect1Inside =
+    V"FunctionBlock" +
     V"Sect2" +
     V"Sect2Inside";
 
@@ -171,6 +174,7 @@ G = P{ "Pandoc",
     V"DescripList" +
     V"CodeBlock" +
     V"TableBlock" +
+    V"Comment" +
     blankchar + V"ParseFail";
 
   Para = P"<p>" * Ct(V"InPara") * P"</p>"^-1 / function (t)
@@ -193,6 +197,11 @@ G = P{ "Pandoc",
       V"FilePathShort" +
       V"RFCRef" +
       V"InternalRef" +
+      V"CodeStruct" +
+      V"CodeFunc" +
+      V"CodeConst" +
+      V"CodeType" +
+      V"CodeParam" +
       V"Comment" +
       (V"Label" / function (e) return pandoc.Span({}, { id = e }) end);
 
@@ -277,7 +286,10 @@ G = P{ "Pandoc",
 
   Emph = P"<em/" * ininline * P"/" / pandoc.Strong;
   Bold = P"<bf/" * ininline * P"/" / pandoc.Strong;
-  It = P"<it/" * ininline * P"/" / pandoc.Emph;
+  It = (
+    P"<it/" * ininline * P"/" +
+    P"<it>" * V"InPara" * P"</it>"
+  ) / pandoc.Emph;
   InlineCodeIt = (P"<m/" + P"<M/") * ininline * P"/" / function (e)
     return pandoc.Emph(e, { class = "code" })
   end;
@@ -343,17 +355,59 @@ G = P{ "Pandoc",
     return pandoc.Code(e, { class = "filepath" })
   end;
 
+  CodeStruct = P'<struct/' * ininline * P'/' / function (e)
+    return pandoc.Code("struct " .. e, { class = "ccode struct" })
+  end;
+
+  CodeFunc = P'<func/' * ininline * P'/' / function (e)
+    return pandoc.Code(e, { class = "ccode func" })
+  end;
+
+  CodeConst = (P'<const/' * ininline * P'/' + P'<const>' * inelement * P'</const>') / function (e)
+    return pandoc.Code(e, { class = "ccode const" })
+  end;
+
+  CodeType = P'<type>' * inelement * P'</type>' / function (t)
+    return pandoc.Code(t, { class = "ccode ctype" })
+  end;
+
+  CodeParam = (P'<param/' * ininline * P'/' + P'<param>' * inelement * P'</param>') / function (p)
+    return pandoc.Code(p, { class = "ccode cparam" })
+  end;
+
   Label = P'<label id="' * C((1 - P('"'))^0) * P'">';
 
   ItemList = P"<itemize>" * Ct((V"ItemListItem" + blankchar)^1) * P"</itemize>" / pandoc.BulletList;
   ItemListItem = P"<item>" * V"InPara";
 
-  DescripList = P"<descrip>" * Ct((V"DescripListItem" + blankchar)^1) * P"</descrip>" / pandoc.DefinitionList;
+  DescripList = P"<descrip>" * Ct((
+    V"DescripListItem" +
+    V"DescripListProgItem" +
+    V"DescripListShortItem" +
+    V"DescripListShortProgItem" +
+    blankchar)^1)
+    * P"</descrip>" / pandoc.DefinitionList;
+
   DescripListItem = P"<tag>" * V"Label" * V"InPara" * "</tag>" * (V"InDescrip" - P"<tag>" - P"</descrip>") / function (l,t,u)
 --    logging.temp("dli", t,u)
     return { pandoc.Span(t, { class = "code", id = l }), { u }}
   end;
 
+  DescripListProgItem = P"<tagp>" * V"InPara" * "</tagp>" * (V"InDescrip" - P"<tagp>" - P"</descrip>") / function (t,u)
+--    logging.temp("dli", t,u)
+    return { pandoc.Span(t, { class = "code" }), { u }}
+  end;
+
+  DescripListShortItem = P"<tag/" * ininline * "/" * (V"InDescrip" - P"<tag" - P"</descrip>") / function (t,u)
+--    logging.temp("dli", t,u)
+    return { pandoc.Span(t, { class = "code" }), { u }}
+  end;
+
+  DescripListShortProgItem = P"<tagp/" * ininline * "/" * (V"InDescrip" - P"<tag" - P"</descrip>") / function (t,u)
+--    logging.temp("dli", t,u)
+    return { pandoc.Span(t, { class = "code" }), { u }}
+  end;
+
   CodeBlock = P'<code>' * C((1 - P'</code>')^0) * P'</code>' / pandoc.CodeBlock;
 
   TableBlockIgnoreBf = P'<bf/' * ininline * '/';
@@ -435,6 +489,55 @@ G = P{ "Pandoc",
       )
   end;
 
+--  FunctionBlock = P'<function><p>' * V"CodeType" * blankmore * V"FunctionName" * blankmore * '(' * V"FunctionHeaderArgs" * ')' * inelement / function (t, n, h, inside)
+  FunctionBlock = P'<function><p>' * V"CodeType" * blankmore
+  * '<funcdef>' * inelement * '</funcdef>' * blankmore
+  * V"FunctionHeaderArgs" * P' --'^0 * Ct(V"InPara") * V"FunctionDescription" * "</function>" / function (t, n, ha, hshort, desc)
+--    logging.temp(t, n, ha, hshort, desc)
+--    logging.temp("desc is", desc)
+    return pandoc.Div(mergetables({
+      pandoc.Header(4, {t, " ", n, ha}, { id = "function-" .. n }),
+      pandoc.Span(mergetables(hshort), { class = "functionshortdesc" }),
+      mergetables(desc)
+    }), { class = "function" }
+  )
+  end;
+
+  FunctionName = P'<funcdef>' * ininline * P'</funcdef>' / pandoc.Str;
+
+  FunctionHeaderArg = V"CodeType"^0 * blankmore * V"CodeParam" / function (t, p)
+    ts = tostring(t)
+    if ts[#ts-1] == "*" then
+      return pandoc.Span({ t, p }, { class = "functionargument" })
+    else
+      return pandoc.Span({ t, " ", p }, { class = "functionargument" })
+    end
+--    if #t then return pandoc.Span({ t[0], p }) else return pandoc.Span({ p }) end
+  end;
+
+  FunctionHeaderArgs = P'(' * Ct(( V"FunctionHeaderArg" * (P',' * blankmore)^0)^0) * P')' / function (a)
+    args = {}
+    for k,v in ipairs(a) do
+      table.insert(args, v)
+      if k < #a then
+       table.insert(args, ", ")
+      end
+    end
+    return pandoc.Span(mergetables({"(", args, ")"}), { class = "functionheaderargs" })
+  end;
+
+  FunctionDescription = Ct(V"FunctionDescSect"^0) / function (inside)
+    return mergetables(inside)
+  end;
+
+  FunctionDescSect = P'<funcsect>' * inelement * Ct((V"Sect3Inside" - P"<funcsect>" - P"</function>")^0) / function (name, inside)
+    return mergetables({
+      pandoc.Header(5, name, {}),
+      mergetables(inside),
+--      "meow end of " .. name,
+    })
+  end;
+
   ParseFail = (1 - P"<sect>" - P"<chapt>" - P"</book>") / function (t) return pandoc.CodeBlock("PARSER FAILED " .. t) end;
 }
 
index d576ee6168df9d398af689fe943dfd43d4cd5f59..8cb5c18aa7f3dc899961bdf4c896f57238923d77 100755 (executable)
@@ -36,7 +36,9 @@ sub process {
     if ($cmd eq "C") { process("$dir/$arg", "Doc"); }
     elsif ($cmd eq "H") {
       push @stack, "H";
-      print OUT "<chapt>$arg\n";
+      my $lbl = lc $arg;
+      $lbl =~ tr/ /-/;
+      print OUT "<chapt>$arg\n<label id=\"$lbl\">\n";
     } elsif ($cmd eq "S") {
       print "    $arg\n";
       my @files = map("$dir/$_", split(' ', $arg));