1*4aee5dffSdan#
2*4aee5dffSdan# 2014 August 24
3*4aee5dffSdan#
4*4aee5dffSdan# The author disclaims copyright to this source code.  In place of
5*4aee5dffSdan# a legal notice, here is a blessing:
6*4aee5dffSdan#
7*4aee5dffSdan#    May you do good and not evil.
8*4aee5dffSdan#    May you find forgiveness for yourself and forgive others.
9*4aee5dffSdan#    May you share freely, never taking more than you give.
10*4aee5dffSdan#
11*4aee5dffSdan#--------------------------------------------------------------------------
12*4aee5dffSdan#
13*4aee5dffSdan# This script extracts the documentation for the API used by fts5 auxiliary
14*4aee5dffSdan# functions from header file fts5.h. It outputs html text on stdout that
15*4aee5dffSdan# is included in the documentation on the web.
16*4aee5dffSdan#
17*4aee5dffSdan
18*4aee5dffSdanset input_file [file join [file dir [info script]] fts5.h]
19*4aee5dffSdanset fd [open $input_file]
20*4aee5dffSdanset data [read $fd]
21*4aee5dffSdanclose $fd
22*4aee5dffSdan
23*4aee5dffSdan
24*4aee5dffSdan# Argument $data is the entire text of the fts5.h file. This function
25*4aee5dffSdan# extracts the definition of the Fts5ExtensionApi structure from it and
26*4aee5dffSdan# returns a key/value list of structure member names and definitions. i.e.
27*4aee5dffSdan#
28*4aee5dffSdan#   iVersion {int iVersion} xUserData {void *(*xUserData)(Fts5Context*)} ...
29*4aee5dffSdan#
30*4aee5dffSdanproc get_struct_members {data} {
31*4aee5dffSdan
32*4aee5dffSdan  # Extract the structure definition from the fts5.h file.
33*4aee5dffSdan  regexp "struct Fts5ExtensionApi {(.*)};" $data -> defn
34*4aee5dffSdan
35*4aee5dffSdan  # Remove all comments from the structure definition
36*4aee5dffSdan  regsub -all {/[*].*?[*]/} $defn {} defn2
37*4aee5dffSdan
38*4aee5dffSdan  set res [list]
39*4aee5dffSdan  foreach member [split $defn2 {;}] {
40*4aee5dffSdan
41*4aee5dffSdan    set member [string trim $member]
42*4aee5dffSdan    if {$member!=""} {
43*4aee5dffSdan      catch { set name [lindex $member end] }
44*4aee5dffSdan      regexp {.*?[(][*]([^)]*)[)]} $member -> name
45*4aee5dffSdan      lappend res $name $member
46*4aee5dffSdan    }
47*4aee5dffSdan  }
48*4aee5dffSdan
49*4aee5dffSdan  set res
50*4aee5dffSdan}
51*4aee5dffSdan
52*4aee5dffSdanproc get_struct_docs {data names} {
53*4aee5dffSdan  # Extract the structure definition from the fts5.h file.
54*4aee5dffSdan  regexp {EXTENSION API FUNCTIONS(.*?)[*]/} $data -> docs
55*4aee5dffSdan
56*4aee5dffSdan  set current_doc    ""
57*4aee5dffSdan  set current_header ""
58*4aee5dffSdan
59*4aee5dffSdan  foreach line [split $docs "\n"] {
60*4aee5dffSdan    regsub {[*]*} $line {} line
61*4aee5dffSdan    if {[regexp {^  } $line]} {
62*4aee5dffSdan      append current_doc "$line\n"
63*4aee5dffSdan    } elseif {[string trim $line]==""} {
64*4aee5dffSdan      if {$current_header!=""} { append current_doc "\n" }
65*4aee5dffSdan    } else {
66*4aee5dffSdan      if {$current_doc != ""} {
67*4aee5dffSdan        lappend res $current_header $current_doc
68*4aee5dffSdan        set current_doc ""
69*4aee5dffSdan      }
70*4aee5dffSdan      set subject n/a
71*4aee5dffSdan      regexp {^ *([[:alpha:]]*)} $line -> subject
72*4aee5dffSdan      if {[lsearch $names $subject]>=0} {
73*4aee5dffSdan        set current_header $subject
74*4aee5dffSdan      } else {
75*4aee5dffSdan        set current_header [string trim $line]
76*4aee5dffSdan      }
77*4aee5dffSdan    }
78*4aee5dffSdan  }
79*4aee5dffSdan
80*4aee5dffSdan  if {$current_doc != ""} {
81*4aee5dffSdan    lappend res $current_header $current_doc
82*4aee5dffSdan  }
83*4aee5dffSdan
84*4aee5dffSdan  set res
85*4aee5dffSdan}
86*4aee5dffSdan
87*4aee5dffSdan# Initialize global array M as a map from Fts5StructureApi member name
88*4aee5dffSdan# to member definition. i.e.
89*4aee5dffSdan#
90*4aee5dffSdan#   iVersion  -> {int iVersion}
91*4aee5dffSdan#   xUserData -> {void *(*xUserData)(Fts5Context*)}
92*4aee5dffSdan#   ...
93*4aee5dffSdan#
94*4aee5dffSdanarray set M [get_struct_members $data]
95*4aee5dffSdan
96*4aee5dffSdan# Initialize global list D as a map from section name to documentation
97*4aee5dffSdan# text. Most (all?) section names are structure member names.
98*4aee5dffSdan#
99*4aee5dffSdanset D [get_struct_docs $data [array names M]]
100*4aee5dffSdan
101*4aee5dffSdanforeach {hdr docs} $D {
102*4aee5dffSdan  if {[info exists M($hdr)]} {
103*4aee5dffSdan    set hdr $M($hdr)
104*4aee5dffSdan  }
105*4aee5dffSdan  puts "<h3><pre>  $hdr</pre></h3>"
106*4aee5dffSdan
107*4aee5dffSdan  set mode ""
108*4aee5dffSdan  set bEmpty 1
109*4aee5dffSdan  foreach line [split [string trim $docs] "\n"] {
110*4aee5dffSdan    if {[string trim $line]==""} {
111*4aee5dffSdan      if {$mode != ""} {puts "</$mode>"}
112*4aee5dffSdan      set mode ""
113*4aee5dffSdan    } elseif {$mode == ""} {
114*4aee5dffSdan      if {[regexp {^     } $line]} {
115*4aee5dffSdan        set mode code
116*4aee5dffSdan      } else {
117*4aee5dffSdan        set mode p
118*4aee5dffSdan      }
119*4aee5dffSdan      puts "<$mode>"
120*4aee5dffSdan    }
121*4aee5dffSdan    puts $line
122*4aee5dffSdan  }
123*4aee5dffSdan  if {$mode != ""} {puts "</$mode>"}
124*4aee5dffSdan}
125*4aee5dffSdan
126*4aee5dffSdan
127*4aee5dffSdan
128*4aee5dffSdan
129*4aee5dffSdan
130*4aee5dffSdan
131*4aee5dffSdan
132