-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathclig
executable file
·208 lines (191 loc) · 5.69 KB
/
clig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
#!/usr/bin/tclsh
# \
exec tclsh "$0" ${1+"$@"}
set BASE /usr/lib/clig-1.9.11.1
set VERSION 0.0.0
set VERDATE 1111-11-11
########################################################################
#
# This file is part of clig, the command line interface generator for
# C and Tcl.
#
# Copyright (C) 1996-2004 Harald Kirsch ([email protected])
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# $Revision: 1.14 $, $Date: 2005/03/01 09:22:49 $
########################################################################
## If still $BASE=="|BASE|", clig was not yet installed and [info
## script] should guide us to the right place
if {[string match |BASE| $BASE]} {
set BASE [file join [file dir [info script]] ..]
}
set auto_path [concat $BASE $auto_path]
##
## Of course we use the clig-library to instrument this very program
##
package require clig $VERSION
namespace import ::clig::\[A-Za-z\]*
## source the files this program is made of
foreach file {
util.tcl genUsage.tcl genStruct.tcl genParse.tcl genDotH.tcl
genDotC.tcl genMan.tcl genDefault.tcl genCheckMandatory.tcl
genShowOptionValues.tcl
} {
source [file join $BASE tcl $file]
}
########################################################################
##
## GLOBAL VARIABLES:
##
## typeMap
## maps between Declaration names and the type-string used in a
## particular language.
set typeMap(C,String) "char*"
set typeMap(C,Int) "int"
set typeMap(C,Long) "long"
set typeMap(C,Float) "float"
set typeMap(C,Double) "double"
## <option> denotes s.th. like `-v'. The string `--' for <option>
## denotes the entries of D describing command line arguments not
## associated with any option (see proc Rest).
##
## D(<option>,type) -- type of <option>, i.e. Int, Float, etc.
## D(<option>,var) -- variable name to be used in generated code
## D(<option>,usage) -- usage string for <option>
## D(<option>,mandatory) -- set to 1, if <option> is mandatory
## D(<option>,default) -- default value(s) for <option>
## D(<option>,min) -- minimum value of <option>'s arguments
## D(<option>,max) -- maximum value of <option>'s arguments
## D(<option>,cmin) -- minimum number of arguments of <option>
## D(<option>,cmax) -- maximum number of arguments of <option>
## D(opts) -- list of all options in D
## D(usage) -- one-line describing specified program
## D(name) -- name of program, used in generated manual page
## D(version) -- version of generated interface, used in usage-message
## D(description) -- description of generated program
## D(commandline) -- name of variable where to store the whole command
## line.
## haveMandatory -- set to 1 if any option is mandatory
## manFile -- name of manual page file to generate
## Program -- the tail of argv0
set Program [file tail $argv0]
########################################################################
#
# Read the spec-file in a rather clean environment. It might be better
# to move all my globals into a namespace. However the context of a
# proc should be similar.
#
proc readSpecfile {file} {
set ::clig::file $file
unset file
if {[catch {source $::clig::file}]} {
global errorInfo
regsub {invoked from.*} $errorInfo {} errorInfo
puts -nonewline stderr "$errorInfo"
exit 1
}
}
########################################################################
##
## Main
##
##
## Of course we declare the parameters of this very program with
## clig.
##
setSpec ::main
source [file join $BASE tcl cmdline.cli]
#parray ::main
##
## Now run the parser
##
set Program [file tail $argv0]
if {[catch {parseCmdline main $Program $argc $argv} err]} {
puts stderr $err
exit 1
}
##
## Additional tests for the command line
##
foreach t $types {
if {-1==[lsearch {C tcl man} $t]} {
puts stderr \
"$Program: type `$t' not supported, use `C' `man' or `tcl'"
exit 1
}
}
##
## Set default for outprefix if not given on the command line
##
if { ![info exist outprefix]} {
set outprefix [file rootname $infile]
}
##
## The declarations we find in infile will go into ::D
##
setSpec ::D
set ::D(opts) {}
readSpecfile $infile
#parray ::D
##
## Check if there are mandatory options. This is needed in several
## code-generation steps.
##
set haveMandatory 0
foreach opt $D(opts) {
if {[info exist D($opt,mandatory)]} {
set haveMandatory 1
break
}
}
##
## Enforce a few required declarations
##
if { ![info exist ::D(usage)] } {
puts stderr "$Program: missing `Usage'-command in `$infile'"
exit 1
}
## Now generate the requested code
foreach t $types {
switch $t {
C {
genDotH $outprefix.h
genDotC $outprefix.c
}
man {
if {![info exist ::D(name)]} {
set msg {}; append msg \
"$Program: missing `Name' declaration in `$infile' " \
"which is needed to create the manual"
puts stderr $msg
exit 1
}
if { ![info exist manFile] } {
set manFile $::D(name)$manExt
} else {
append manFile $manExt
}
genMan $manFile
}
tcl {
puts stderr "$Program: sorry, type `tcl' not yet implemented"
}
}
}
########################################################################
## Local Variables: ##
## mode:tcl ##
## End: ##