os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/tools/checkLibraryDoc.tcl
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
# checkLibraryDoc.tcl --
sl@0
     2
#
sl@0
     3
# This script attempts to determine what APIs exist in the source base that 
sl@0
     4
# have not been documented.  By grepping through all of the doc/*.3 man 
sl@0
     5
# pages, looking for "Pkg_*" (e.g., Tcl_ or Tk_), and comparing this list
sl@0
     6
# against the list of Pkg_ APIs found in the source (e.g., tcl8.2/*/*.[ch])
sl@0
     7
# we create six lists:
sl@0
     8
#      1) APIs in Source not in Docs.
sl@0
     9
#      2) APIs in Docs not in Source.
sl@0
    10
#      3) Internal APIs and structs.
sl@0
    11
#      4) Misc APIs and structs that we are not documenting.
sl@0
    12
#      5) Command APIs (e.g., Tcl_ArrayObjCmd.)
sl@0
    13
#      6) Proc pointers (e.g., Tcl_CloseProc.)
sl@0
    14
# 
sl@0
    15
# Note: Each list is "a best guess" approximation.  If developers write
sl@0
    16
# non-standard code, this script will produce erroneous results.  Each
sl@0
    17
# list should be carefully checked for accuracy. 
sl@0
    18
#
sl@0
    19
# Copyright (c) 1998-1999 by Scriptics Corporation.
sl@0
    20
# All rights reserved.
sl@0
    21
# 
sl@0
    22
# RCS: @(#) $Id: checkLibraryDoc.tcl,v 1.7 2002/01/15 17:55:30 dgp Exp $
sl@0
    23
sl@0
    24
sl@0
    25
lappend auto_path "c:/program\ files/tclpro1.2/win32-ix86/bin"
sl@0
    26
#lappend auto_path "/home/surles/cvs/tclx8.0/tcl/unix"
sl@0
    27
if {[catch {package require Tclx}]} {
sl@0
    28
    puts "error: could not load TclX.  Please set TCL_LIBRARY."
sl@0
    29
    exit 1
sl@0
    30
}
sl@0
    31
sl@0
    32
# A list of structs that are known to be undocumented.
sl@0
    33
sl@0
    34
set StructList {
sl@0
    35
    Tcl_AsyncHandler \
sl@0
    36
    Tcl_CallFrame \
sl@0
    37
    Tcl_Condition \
sl@0
    38
    Tcl_Encoding \
sl@0
    39
    Tcl_EncodingState \
sl@0
    40
    Tcl_EncodingType \
sl@0
    41
    Tcl_HashEntry \
sl@0
    42
    Tcl_HashSearch \
sl@0
    43
    Tcl_HashTable \
sl@0
    44
    Tcl_Mutex \
sl@0
    45
    Tcl_Pid \
sl@0
    46
    Tcl_QueuePosition \
sl@0
    47
    Tcl_ResolvedVarInfo \
sl@0
    48
    Tcl_SavedResult \
sl@0
    49
    Tcl_ThreadDataKey \
sl@0
    50
    Tcl_ThreadId \
sl@0
    51
    Tcl_Time \
sl@0
    52
    Tcl_TimerToken \
sl@0
    53
    Tcl_Token \
sl@0
    54
    Tcl_Trace \
sl@0
    55
    Tcl_Value \
sl@0
    56
    Tcl_ValueType \
sl@0
    57
    Tcl_Var \
sl@0
    58
    Tk_3DBorder \
sl@0
    59
    Tk_ArgvInfo \
sl@0
    60
    Tk_BindingTable \
sl@0
    61
    Tk_Canvas \
sl@0
    62
    Tk_CanvasTextInfo \
sl@0
    63
    Tk_ConfigSpec \
sl@0
    64
    Tk_ConfigTypes \
sl@0
    65
    Tk_Cursor \
sl@0
    66
    Tk_CustomOption \
sl@0
    67
    Tk_ErrorHandler \
sl@0
    68
    Tk_FakeWin \
sl@0
    69
    Tk_Font \
sl@0
    70
    Tk_FontMetrics \
sl@0
    71
    Tk_GeomMgr \
sl@0
    72
    Tk_Image \
sl@0
    73
    Tk_ImageMaster \
sl@0
    74
    Tk_ImageType \
sl@0
    75
    Tk_Item \
sl@0
    76
    Tk_ItemType \
sl@0
    77
    Tk_OptionSpec\
sl@0
    78
    Tk_OptionTable \
sl@0
    79
    Tk_OptionType \
sl@0
    80
    Tk_PhotoHandle \
sl@0
    81
    Tk_PhotoImageBlock \
sl@0
    82
    Tk_PhotoImageFormat \
sl@0
    83
    Tk_PostscriptInfo \
sl@0
    84
    Tk_SavedOption \
sl@0
    85
    Tk_SavedOptions \
sl@0
    86
    Tk_SegType \
sl@0
    87
    Tk_TextLayout \
sl@0
    88
    Tk_Window \
sl@0
    89
}
sl@0
    90
sl@0
    91
# Misc junk that appears in the comments of the source.  This just 
sl@0
    92
# allows us to filter comments that "fool" the script.
sl@0
    93
sl@0
    94
set CommentList {
sl@0
    95
    Tcl_Create\[Obj\]Command \
sl@0
    96
    Tcl_DecrRefCount\\n \
sl@0
    97
    Tcl_NewObj\\n \
sl@0
    98
    Tk_GetXXX \
sl@0
    99
}
sl@0
   100
sl@0
   101
# Main entry point to this script.
sl@0
   102
sl@0
   103
proc main {} {
sl@0
   104
    global argv0 
sl@0
   105
    global argv 
sl@0
   106
sl@0
   107
    set len [llength $argv]
sl@0
   108
    if {($len != 2) && ($len != 3)} {
sl@0
   109
	puts "usage: $argv0 pkgName pkgDir \[outFile\]"
sl@0
   110
	puts "   pkgName == Tcl,Tk"
sl@0
   111
	puts "   pkgDir  == /home/surles/cvs/tcl8.2"
sl@0
   112
	exit 1
sl@0
   113
    }
sl@0
   114
sl@0
   115
    set pkg [lindex $argv 0]
sl@0
   116
    set dir [lindex $argv 1]
sl@0
   117
    if {[llength $argv] == 3} {
sl@0
   118
	set file [open [lindex $argv 2] w]
sl@0
   119
    } else {
sl@0
   120
	set file stdout
sl@0
   121
    }
sl@0
   122
sl@0
   123
    foreach {c d} [compare [grepCode $dir $pkg] [grepDocs $dir $pkg]] {}
sl@0
   124
    filter $c $d $dir $pkg $file
sl@0
   125
sl@0
   126
    if {$file != "stdout"} {
sl@0
   127
	close $file
sl@0
   128
    }
sl@0
   129
    return
sl@0
   130
}
sl@0
   131
    
sl@0
   132
# Intersect the two list and write out the sets of APIs in one
sl@0
   133
# list that is not in the other.
sl@0
   134
sl@0
   135
proc compare {list1 list2} {
sl@0
   136
    set inter [intersect3 $list1 $list2]
sl@0
   137
    return [list [lindex $inter 0] [lindex $inter 2]]
sl@0
   138
}
sl@0
   139
sl@0
   140
# Filter the lists into the six lists we report on.  Then write
sl@0
   141
# the results to the file.
sl@0
   142
sl@0
   143
proc filter {code docs dir pkg {outFile stdout}} {
sl@0
   144
    set apis  {}
sl@0
   145
sl@0
   146
    # A list of Tcl command APIs.  These are not documented.
sl@0
   147
    # This list should just be verified for accuracy.
sl@0
   148
sl@0
   149
    set cmds  {}
sl@0
   150
    
sl@0
   151
    # A list of proc pointer structs.  These are not documented.
sl@0
   152
    # This list should just be verified for accuracy.
sl@0
   153
sl@0
   154
    set procs {}
sl@0
   155
sl@0
   156
    # A list of internal declarations.  These are not documented.
sl@0
   157
    # This list should just be verified for accuracy.
sl@0
   158
sl@0
   159
    set decls [grepDecl $dir $pkg]
sl@0
   160
sl@0
   161
    # A list of misc. procedure declarations that are not documented.
sl@0
   162
    # This list should just be verified for accuracy.
sl@0
   163
sl@0
   164
    set misc [grepMisc $dir $pkg]
sl@0
   165
sl@0
   166
    set pat1 ".*(${pkg}_\[A-z0-9]+).*$"
sl@0
   167
    
sl@0
   168
    # A list of APIs in the source, not in the docs.
sl@0
   169
    # This list should just be verified for accuracy.
sl@0
   170
sl@0
   171
    foreach x $code {
sl@0
   172
	if {[string match *Cmd $x]} {
sl@0
   173
	    if {[string match ${pkg}* $x]} {
sl@0
   174
		lappend cmds $x
sl@0
   175
	    }
sl@0
   176
	} elseif {[string match *Proc $x]} {
sl@0
   177
	    if {[string match ${pkg}* $x]} {
sl@0
   178
		lappend procs $x
sl@0
   179
	    }
sl@0
   180
	} elseif {[lsearch -exact $decls $x] >= 0} {
sl@0
   181
	    # No Op.
sl@0
   182
	} elseif {[lsearch -exact $misc $x] >= 0} {
sl@0
   183
	    # No Op.
sl@0
   184
	} else {
sl@0
   185
	    lappend apis $x
sl@0
   186
	}
sl@0
   187
    }
sl@0
   188
sl@0
   189
    dump $apis  "APIs in Source not in Docs." $outFile
sl@0
   190
    dump $docs  "APIs in Docs not in Source." $outFile
sl@0
   191
    dump $decls "Internal APIs and structs."  $outFile
sl@0
   192
    dump $misc  "Misc APIs and structs that we are not documenting." $outFile
sl@0
   193
    dump $cmds  "Command APIs."  $outFile
sl@0
   194
    dump $procs "Proc pointers." $outFile
sl@0
   195
    return
sl@0
   196
}
sl@0
   197
sl@0
   198
# Print the list of APIs if the list is not null.
sl@0
   199
sl@0
   200
proc dump {list title file} {
sl@0
   201
    if {$list != {}} {
sl@0
   202
	puts $file ""
sl@0
   203
	puts $file $title
sl@0
   204
	puts $file "---------------------------------------------------------"
sl@0
   205
	foreach x $list {
sl@0
   206
	    puts $file $x
sl@0
   207
	}
sl@0
   208
    }
sl@0
   209
}
sl@0
   210
sl@0
   211
# Grep into "dir/*/*.[ch]" looking for APIs that match $pkg_*.
sl@0
   212
# (e.g., Tcl_Exit).  Return a list of APIs.
sl@0
   213
sl@0
   214
proc grepCode {dir pkg} {
sl@0
   215
    set apis [myGrep "${pkg}_\.\*" "${dir}/\*/\*\.\[ch\]"]
sl@0
   216
    set pat1 ".*(${pkg}_\[A-z0-9]+).*$"
sl@0
   217
sl@0
   218
    foreach a $apis {
sl@0
   219
	if {[regexp --  $pat1 $a main n1]} {
sl@0
   220
	    set result([string trim $n1]) 1
sl@0
   221
	}
sl@0
   222
    }
sl@0
   223
    return [lsort [array names result]]
sl@0
   224
}
sl@0
   225
sl@0
   226
# Grep into "dir/doc/*.3" looking for APIs that match $pkg_*.
sl@0
   227
# (e.g., Tcl_Exit).  Return a list of APIs.
sl@0
   228
sl@0
   229
proc grepDocs {dir pkg} {
sl@0
   230
    set apis [myGrep "\\fB${pkg}_\.\*\\fR" "${dir}/doc/\*\.3"]
sl@0
   231
    set pat1 ".*(${pkg}_\[A-z0-9]+)\\\\fR.*$"
sl@0
   232
sl@0
   233
    foreach a $apis {
sl@0
   234
	if {[regexp -- $pat1 $a main n1]} {
sl@0
   235
	    set result([string trim $n1]) 1
sl@0
   236
	}
sl@0
   237
    }
sl@0
   238
    return [lsort [array names result]]
sl@0
   239
}
sl@0
   240
sl@0
   241
# Grep into "generic/pkgIntDecls.h" looking for APIs that match $pkg_*.
sl@0
   242
# (e.g., Tcl_Export).  Return a list of APIs.
sl@0
   243
sl@0
   244
proc grepDecl {dir pkg} {
sl@0
   245
    set file [file join $dir generic "[string tolower $pkg]IntDecls.h"] 
sl@0
   246
    set apis [myGrep "^EXTERN.*\[ \t\]${pkg}_.*" $file]
sl@0
   247
    set pat1 ".*(${pkg}_\[A-z0-9]+).*$"
sl@0
   248
sl@0
   249
    foreach a $apis {
sl@0
   250
	if {[regexp -- $pat1 $a main n1]} {
sl@0
   251
	    set result([string trim $n1]) 1
sl@0
   252
	}
sl@0
   253
    }
sl@0
   254
    return [lsort [array names result]]
sl@0
   255
}
sl@0
   256
sl@0
   257
# Grep into "*/*.[ch]" looking for APIs that match $pkg_Db*.
sl@0
   258
# (e.g., Tcl_DbCkalloc).  Return a list of APIs.
sl@0
   259
sl@0
   260
proc grepMisc {dir pkg} {
sl@0
   261
    global CommentList
sl@0
   262
    global StructList
sl@0
   263
    
sl@0
   264
    set apis [myGrep "^EXTERN.*\[ \t\]${pkg}_Db.*" "${dir}/\*/\*\.\[ch\]"]
sl@0
   265
    set pat1 ".*(${pkg}_\[A-z0-9]+).*$"
sl@0
   266
sl@0
   267
    foreach a $apis {
sl@0
   268
	if {[regexp -- $pat1 $a main n1]} {
sl@0
   269
	    set dbg([string trim $n1]) 1
sl@0
   270
	}
sl@0
   271
    }
sl@0
   272
sl@0
   273
    set result {}
sl@0
   274
    eval {lappend result} $StructList
sl@0
   275
    eval {lappend result} [lsort [array names dbg]]
sl@0
   276
    eval {lappend result} $CommentList
sl@0
   277
    return $result
sl@0
   278
}
sl@0
   279
sl@0
   280
proc myGrep {searchPat globPat} {
sl@0
   281
    set result {}
sl@0
   282
    foreach file [glob -nocomplain $globPat] {
sl@0
   283
	set file [open $file r]
sl@0
   284
	set data [read $file]
sl@0
   285
	close $file
sl@0
   286
	foreach line [split $data "\n"] {
sl@0
   287
	    if {[regexp "^.*${searchPat}.*\$" $line]} {
sl@0
   288
		lappend result $line
sl@0
   289
	    }
sl@0
   290
	}
sl@0
   291
    }
sl@0
   292
    return $result
sl@0
   293
}
sl@0
   294
main
sl@0
   295