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 1848d70140Sdanset ::fts5_docs_output "" 1948d70140Sdanif {[info commands hd_putsnl]==""} { 20*27277c4eSdan if {[llength $argv]>0} { set ::extract_api_docs_mode [lindex $argv 0] } 2148d70140Sdan proc output {text} { 2248d70140Sdan puts $text 2348d70140Sdan } 2448d70140Sdan} else { 2548d70140Sdan proc output {text} { 26*27277c4eSdan append ::fts5_docs_output "$text\n" 2748d70140Sdan } 2848d70140Sdan} 29*27277c4eSdanif {[info exists ::extract_api_docs_mode]==0} {set ::extract_api_docs_mode api} 30*27277c4eSdan 3148d70140Sdan 324aee5dffSdanset input_file [file join [file dir [info script]] fts5.h] 334aee5dffSdanset fd [open $input_file] 344aee5dffSdanset data [read $fd] 354aee5dffSdanclose $fd 364aee5dffSdan 374aee5dffSdan 384aee5dffSdan# Argument $data is the entire text of the fts5.h file. This function 394aee5dffSdan# extracts the definition of the Fts5ExtensionApi structure from it and 404aee5dffSdan# returns a key/value list of structure member names and definitions. i.e. 414aee5dffSdan# 424aee5dffSdan# iVersion {int iVersion} xUserData {void *(*xUserData)(Fts5Context*)} ... 434aee5dffSdan# 444aee5dffSdanproc get_struct_members {data} { 454aee5dffSdan 464aee5dffSdan # Extract the structure definition from the fts5.h file. 47*27277c4eSdan regexp "struct Fts5ExtensionApi {(.*?)};" $data -> defn 484aee5dffSdan 494aee5dffSdan # Remove all comments from the structure definition 504aee5dffSdan regsub -all {/[*].*?[*]/} $defn {} defn2 514aee5dffSdan 524aee5dffSdan set res [list] 534aee5dffSdan foreach member [split $defn2 {;}] { 544aee5dffSdan 554aee5dffSdan set member [string trim $member] 564aee5dffSdan if {$member!=""} { 574aee5dffSdan catch { set name [lindex $member end] } 584aee5dffSdan regexp {.*?[(][*]([^)]*)[)]} $member -> name 594aee5dffSdan lappend res $name $member 604aee5dffSdan } 614aee5dffSdan } 624aee5dffSdan 634aee5dffSdan set res 644aee5dffSdan} 654aee5dffSdan 664aee5dffSdanproc get_struct_docs {data names} { 674aee5dffSdan # Extract the structure definition from the fts5.h file. 684aee5dffSdan regexp {EXTENSION API FUNCTIONS(.*?)[*]/} $data -> docs 694aee5dffSdan 704aee5dffSdan set current_doc "" 714aee5dffSdan set current_header "" 724aee5dffSdan 734aee5dffSdan foreach line [split $docs "\n"] { 744aee5dffSdan regsub {[*]*} $line {} line 754aee5dffSdan if {[regexp {^ } $line]} { 764aee5dffSdan append current_doc "$line\n" 774aee5dffSdan } elseif {[string trim $line]==""} { 784aee5dffSdan if {$current_header!=""} { append current_doc "\n" } 794aee5dffSdan } else { 804aee5dffSdan if {$current_doc != ""} { 814aee5dffSdan lappend res $current_header $current_doc 824aee5dffSdan set current_doc "" 834aee5dffSdan } 844aee5dffSdan set subject n/a 854aee5dffSdan regexp {^ *([[:alpha:]]*)} $line -> subject 864aee5dffSdan if {[lsearch $names $subject]>=0} { 874aee5dffSdan set current_header $subject 884aee5dffSdan } else { 894aee5dffSdan set current_header [string trim $line] 904aee5dffSdan } 914aee5dffSdan } 924aee5dffSdan } 934aee5dffSdan 944aee5dffSdan if {$current_doc != ""} { 954aee5dffSdan lappend res $current_header $current_doc 964aee5dffSdan } 974aee5dffSdan 984aee5dffSdan set res 994aee5dffSdan} 1004aee5dffSdan 101*27277c4eSdanproc get_tokenizer_docs {data} { 102*27277c4eSdan regexp {(xCreate:.*?)[*]/} $data -> docs 103*27277c4eSdan 104*27277c4eSdan set res "<dl>\n" 105*27277c4eSdan foreach line [split [string trim $docs] "\n"] { 106*27277c4eSdan regexp {[*][*](.*)} $line -> line 107*27277c4eSdan if {[regexp {^ ?x.*:} $line]} { 108*27277c4eSdan append res "<dt><b>$line</b></dt><dd><p style=margin-top:0>\n" 109*27277c4eSdan continue 110*27277c4eSdan } 111*27277c4eSdan if {[string trim $line] == ""} { 112*27277c4eSdan append res "<p>\n" 113*27277c4eSdan } else { 114*27277c4eSdan append res "$line\n" 115*27277c4eSdan } 116*27277c4eSdan } 117*27277c4eSdan append res "</dl>\n" 118*27277c4eSdan 119*27277c4eSdan set res 120*27277c4eSdan} 121*27277c4eSdan 122*27277c4eSdanproc get_api_docs {data} { 1234aee5dffSdan # Initialize global array M as a map from Fts5StructureApi member name 1244aee5dffSdan # to member definition. i.e. 1254aee5dffSdan # 1264aee5dffSdan # iVersion -> {int iVersion} 1274aee5dffSdan # xUserData -> {void *(*xUserData)(Fts5Context*)} 1284aee5dffSdan # ... 1294aee5dffSdan # 1304aee5dffSdan array set M [get_struct_members $data] 1314aee5dffSdan 1324aee5dffSdan # Initialize global list D as a map from section name to documentation 1334aee5dffSdan # text. Most (all?) section names are structure member names. 1344aee5dffSdan # 1354aee5dffSdan set D [get_struct_docs $data [array names M]] 1364aee5dffSdan 137*27277c4eSdan foreach {sub docs} $D { 138*27277c4eSdan if {[info exists M($sub)]} { 139*27277c4eSdan set hdr $M($sub) 140*27277c4eSdan set link " id=$sub" 141*27277c4eSdan } else { 142*27277c4eSdan set link "" 1434aee5dffSdan } 144*27277c4eSdan 145*27277c4eSdan output "<hr color=#eeeee style=\"margin:1em 8.4ex 0 8.4ex;\"$link>" 146*27277c4eSdan set style "padding-left:6ex;font-size:1.4em;display:block" 147*27277c4eSdan output "<h style=\"$style\"><pre>$hdr</pre></h>" 1484aee5dffSdan 1494aee5dffSdan set mode "" 1504aee5dffSdan set bEmpty 1 1514aee5dffSdan foreach line [split [string trim $docs] "\n"] { 1524aee5dffSdan if {[string trim $line]==""} { 15348d70140Sdan if {$mode != ""} {output "</$mode>"} 1544aee5dffSdan set mode "" 1554aee5dffSdan } elseif {$mode == ""} { 1564aee5dffSdan if {[regexp {^ } $line]} { 15748d70140Sdan set mode codeblock 1584aee5dffSdan } else { 1594aee5dffSdan set mode p 1604aee5dffSdan } 16148d70140Sdan output "<$mode>" 1624aee5dffSdan } 16348d70140Sdan output $line 1644aee5dffSdan } 16548d70140Sdan if {$mode != ""} {output "</$mode>"} 1664aee5dffSdan } 167*27277c4eSdan} 168*27277c4eSdan 169*27277c4eSdanproc get_fts5_struct {data start end} { 170*27277c4eSdan set res "" 171*27277c4eSdan set bOut 0 172*27277c4eSdan foreach line [split $data "\n"] { 173*27277c4eSdan if {$bOut==0} { 174*27277c4eSdan if {[regexp $start $line]} { 175*27277c4eSdan set bOut 1 176*27277c4eSdan } 177*27277c4eSdan } 178*27277c4eSdan 179*27277c4eSdan if {$bOut} { 180*27277c4eSdan append res "$line\n" 181*27277c4eSdan } 182*27277c4eSdan 183*27277c4eSdan if {$bOut} { 184*27277c4eSdan if {[regexp $end $line]} { 185*27277c4eSdan set bOut 0 186*27277c4eSdan } 187*27277c4eSdan } 188*27277c4eSdan } 189*27277c4eSdan 190*27277c4eSdan set map [list /* <i>/* */ */</i>] 191*27277c4eSdan string map $map $res 192*27277c4eSdan} 193*27277c4eSdan 194*27277c4eSdanproc main {data} { 195*27277c4eSdan switch $::extract_api_docs_mode { 196*27277c4eSdan fts5_api { 197*27277c4eSdan output [get_fts5_struct $data "typedef struct fts5_api" "^\};"] 198*27277c4eSdan } 199*27277c4eSdan 200*27277c4eSdan fts5_tokenizer { 201*27277c4eSdan output [get_fts5_struct $data "typedef struct Fts5Tokenizer" "^\};"] 202*27277c4eSdan } 203*27277c4eSdan 204*27277c4eSdan fts5_extension { 205*27277c4eSdan output [get_fts5_struct $data "typedef.*Fts5ExtensionApi" "^.;"] 206*27277c4eSdan } 207*27277c4eSdan 208*27277c4eSdan Fts5ExtensionApi { 209*27277c4eSdan set struct [get_fts5_struct $data "^struct Fts5ExtensionApi" "^.;"] 210*27277c4eSdan set map [list] 211*27277c4eSdan foreach {k v} [get_struct_members $data] { 212*27277c4eSdan if {[string match x* $k]==0} continue 213*27277c4eSdan lappend map $k "<a href=#$k>$k</a>" 214*27277c4eSdan } 215*27277c4eSdan output [string map $map $struct] 216*27277c4eSdan } 217*27277c4eSdan 218*27277c4eSdan api { 219*27277c4eSdan get_api_docs $data 220*27277c4eSdan } 221*27277c4eSdan 222*27277c4eSdan tokenizer_api { 223*27277c4eSdan output [get_tokenizer_docs $data] 224*27277c4eSdan } 225*27277c4eSdan 226*27277c4eSdan default { 227*27277c4eSdan } 228*27277c4eSdan } 229*27277c4eSdan} 230*27277c4eSdanmain $data 2314aee5dffSdan 23248d70140Sdanset ::fts5_docs_output 2334aee5dffSdan 2344aee5dffSdan 2354aee5dffSdan 2364aee5dffSdan 2374aee5dffSdan 238