14aee5dffSdan#
24aee5dffSdan# 2014 August 24
34aee5dffSdan#
44aee5dffSdan# The author disclaims copyright to this source code.  In place of
54aee5dffSdan# a legal notice, here is a blessing:
64aee5dffSdan#
74aee5dffSdan#    May you do good and not evil.
84aee5dffSdan#    May you find forgiveness for yourself and forgive others.
94aee5dffSdan#    May you share freely, never taking more than you give.
104aee5dffSdan#
114aee5dffSdan#--------------------------------------------------------------------------
124aee5dffSdan#
134aee5dffSdan# This script extracts the documentation for the API used by fts5 auxiliary
144aee5dffSdan# functions from header file fts5.h. It outputs html text on stdout that
154aee5dffSdan# is included in the documentation on the web.
164aee5dffSdan#
174aee5dffSdan
18*48d70140Sdanset ::fts5_docs_output ""
19*48d70140Sdanif {[info commands hd_putsnl]==""} {
20*48d70140Sdan  proc output {text} {
21*48d70140Sdan    puts $text
22*48d70140Sdan  }
23*48d70140Sdan} else {
24*48d70140Sdan  proc output {text} {
25*48d70140Sdan    append ::fts5_docs_output $text
26*48d70140Sdan  }
27*48d70140Sdan}
28*48d70140Sdan
294aee5dffSdanset input_file [file join [file dir [info script]] fts5.h]
304aee5dffSdanset fd [open $input_file]
314aee5dffSdanset data [read $fd]
324aee5dffSdanclose $fd
334aee5dffSdan
344aee5dffSdan
354aee5dffSdan# Argument $data is the entire text of the fts5.h file. This function
364aee5dffSdan# extracts the definition of the Fts5ExtensionApi structure from it and
374aee5dffSdan# returns a key/value list of structure member names and definitions. i.e.
384aee5dffSdan#
394aee5dffSdan#   iVersion {int iVersion} xUserData {void *(*xUserData)(Fts5Context*)} ...
404aee5dffSdan#
414aee5dffSdanproc get_struct_members {data} {
424aee5dffSdan
434aee5dffSdan  # Extract the structure definition from the fts5.h file.
444aee5dffSdan  regexp "struct Fts5ExtensionApi {(.*)};" $data -> defn
454aee5dffSdan
464aee5dffSdan  # Remove all comments from the structure definition
474aee5dffSdan  regsub -all {/[*].*?[*]/} $defn {} defn2
484aee5dffSdan
494aee5dffSdan  set res [list]
504aee5dffSdan  foreach member [split $defn2 {;}] {
514aee5dffSdan
524aee5dffSdan    set member [string trim $member]
534aee5dffSdan    if {$member!=""} {
544aee5dffSdan      catch { set name [lindex $member end] }
554aee5dffSdan      regexp {.*?[(][*]([^)]*)[)]} $member -> name
564aee5dffSdan      lappend res $name $member
574aee5dffSdan    }
584aee5dffSdan  }
594aee5dffSdan
604aee5dffSdan  set res
614aee5dffSdan}
624aee5dffSdan
634aee5dffSdanproc get_struct_docs {data names} {
644aee5dffSdan  # Extract the structure definition from the fts5.h file.
654aee5dffSdan  regexp {EXTENSION API FUNCTIONS(.*?)[*]/} $data -> docs
664aee5dffSdan
674aee5dffSdan  set current_doc    ""
684aee5dffSdan  set current_header ""
694aee5dffSdan
704aee5dffSdan  foreach line [split $docs "\n"] {
714aee5dffSdan    regsub {[*]*} $line {} line
724aee5dffSdan    if {[regexp {^  } $line]} {
734aee5dffSdan      append current_doc "$line\n"
744aee5dffSdan    } elseif {[string trim $line]==""} {
754aee5dffSdan      if {$current_header!=""} { append current_doc "\n" }
764aee5dffSdan    } else {
774aee5dffSdan      if {$current_doc != ""} {
784aee5dffSdan        lappend res $current_header $current_doc
794aee5dffSdan        set current_doc ""
804aee5dffSdan      }
814aee5dffSdan      set subject n/a
824aee5dffSdan      regexp {^ *([[:alpha:]]*)} $line -> subject
834aee5dffSdan      if {[lsearch $names $subject]>=0} {
844aee5dffSdan        set current_header $subject
854aee5dffSdan      } else {
864aee5dffSdan        set current_header [string trim $line]
874aee5dffSdan      }
884aee5dffSdan    }
894aee5dffSdan  }
904aee5dffSdan
914aee5dffSdan  if {$current_doc != ""} {
924aee5dffSdan    lappend res $current_header $current_doc
934aee5dffSdan  }
944aee5dffSdan
954aee5dffSdan  set res
964aee5dffSdan}
974aee5dffSdan
984aee5dffSdan# Initialize global array M as a map from Fts5StructureApi member name
994aee5dffSdan# to member definition. i.e.
1004aee5dffSdan#
1014aee5dffSdan#   iVersion  -> {int iVersion}
1024aee5dffSdan#   xUserData -> {void *(*xUserData)(Fts5Context*)}
1034aee5dffSdan#   ...
1044aee5dffSdan#
1054aee5dffSdanarray set M [get_struct_members $data]
1064aee5dffSdan
1074aee5dffSdan# Initialize global list D as a map from section name to documentation
1084aee5dffSdan# text. Most (all?) section names are structure member names.
1094aee5dffSdan#
1104aee5dffSdanset D [get_struct_docs $data [array names M]]
1114aee5dffSdan
1124aee5dffSdanforeach {hdr docs} $D {
1134aee5dffSdan  if {[info exists M($hdr)]} {
1144aee5dffSdan    set hdr $M($hdr)
1154aee5dffSdan  }
116*48d70140Sdan  output "<h style=\"font-size:1.4em;background-color:#EEEEEE;display:block\"><pre>  $hdr</pre></h>"
1174aee5dffSdan
1184aee5dffSdan  set mode ""
1194aee5dffSdan  set bEmpty 1
1204aee5dffSdan  foreach line [split [string trim $docs] "\n"] {
1214aee5dffSdan    if {[string trim $line]==""} {
122*48d70140Sdan      if {$mode != ""} {output "</$mode>"}
1234aee5dffSdan      set mode ""
1244aee5dffSdan    } elseif {$mode == ""} {
1254aee5dffSdan      if {[regexp {^     } $line]} {
126*48d70140Sdan        set mode codeblock
1274aee5dffSdan      } else {
1284aee5dffSdan        set mode p
1294aee5dffSdan      }
130*48d70140Sdan      output "<$mode>"
1314aee5dffSdan    }
132*48d70140Sdan    output $line
1334aee5dffSdan  }
134*48d70140Sdan  if {$mode != ""} {output "</$mode>"}
1354aee5dffSdan}
1364aee5dffSdan
137*48d70140Sdanset ::fts5_docs_output
1384aee5dffSdan
1394aee5dffSdan
1404aee5dffSdan
1414aee5dffSdan
1424aee5dffSdan
143