Commit | Line | Data |
---|---|---|
bac41a7b A |
1 | % file: .../doc/tcl.tex |
2 | ||
a66d0d4a | 3 | % $Header: /cvs/root/Security/SecuritySNACCRuntime/doc/Attic/tcl.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $ |
bac41a7b A |
4 | % $Log: tcl.tex,v $ |
5 | % Revision 1.1.1.1 2001/05/18 23:14:10 mb | |
6 | % Move from private repository to open source repository | |
7 | % | |
8 | % Revision 1.1.1.1 1999/03/16 18:05:54 aram | |
9 | % Originals from SMIME Free Library. | |
10 | % | |
11 | % Revision 1.1 1997/01/01 22:47:40 rj | |
12 | % first check-in | |
13 | % | |
14 | ||
15 | \chapter{\label{tcl-if-chapter}Tcl Interface} | |
16 | ||
17 | \section{\label{intro-tcl-section}Introduction} | |
18 | ||
19 | This chapter describes the Snacc's Tcl interface, or: the metacode's link to the outside world. | |
20 | ||
21 | Tcl is a simple scripting language which the author, John K. Ousterhout, describes in his book titled ``Tcl and the TK Toolkit'' \cite{tcl-book}. | |
22 | Tcl's purpose is to be embedded into other applications, to provide a user interface by extending the language. | |
23 | Tk, an implementation of the Motif look and feel, is the first and best known extension to Tcl and is described in the same book. | |
24 | ||
25 | Tcl has got only one data type, the NUL terminated character string. | |
26 | Tcl supports other data types like integers and lists, but they are represented as strings. | |
27 | A function operating on an integer first converts the string into an integer, performs its operation, converts the resulting value back into another string and returns it to the Tcl interpreter. | |
28 | Since lists and even the Tcl procedures are kept as strings, Tcl is rather slow. | |
29 | Computations in Tcl should best be kept at a minimum, and all intensive work should be wrapped into C or C++ functions and be made available as Tcl commands. | |
30 | ||
31 | Since procedures and bodies of loops are kept in string form and parsed for every invocation, comments should be put outside code that is executed \emph{very} often. | |
32 | ||
33 | From Tcl's point of view, Snacc's Tcl interface is nothing but yet another Tcl extension. | |
34 | The Snacc Tcl interface extends the Tcl language by only one command, {\Tcl snacc}. | |
35 | The first argument to this command specifies the action to be taken. | |
36 | This method is very practical for combining Tcl extensions since it avoids collisions with new command names from other extensions. | |
37 | For example, the Tcl core defines an {\Tcl open} command. | |
38 | Snacc's Tcl interface wants to offer one as well and has to choose another name. | |
39 | This could have been done by naming it {\Tcl snacc\_open}, but I think it is better to stick to Tcl's well established convention and so the Tcl interface's open command became {\Tcl snacc open}. | |
40 | To simplify the wording, I will refer to the `snacc subcommands' simply as `commands'. | |
41 | ||
42 | The usual (non-metacode) snacc generated functions operate on memory buffers containing BER encoded data; they convert them into hierarchical C++ data structures and vice versa. | |
43 | ||
44 | The Tcl interface is designed to allow controlled fine grained access to this hierarchical C++ data structure, to read and modify its contents. | |
45 | While both the C++ code and the Tcl look very similar, for example\dots\\[1ex] | |
46 | {\C | |
47 | // this is C++ code\\ | |
48 | x-->foo-->bar = 42;\\[1ex] | |
49 | } | |
50 | \dots\ and\dots\\[1ex] | |
51 | {\Tcl | |
52 | \# this is Tcl code\\ | |
53 | snacc set \{x foo bar\} 42 | |
54 | } | |
55 | ||
56 | \dots\ the C++ code gets compiled and the identifiers get turned into pointers and numeric offsets, and the Tcl code gets interpreted and has to mimic the C++ compiler at run time. | |
57 | This is what the metacode from chapter~\ref{meta-chapter} is for. | |
58 | ||
59 | To enable snacc's Tcl code generator, you have to give an additional {\ufn -tcl} option, followed by the list of PDU types. | |
60 | The {\ufn -meta} option can (and should) be omitted. | |
61 | ||
62 | \section{The {\Tcl snacc} Tcl command} | |
63 | ||
64 | This section explains the Tcl (sub)commands provided by the Snacc extension. | |
65 | The commands are grouped in three catagories, commands operating on files (both their external and internal representation), commands accessing the meta information and commands operating on the content itself. | |
66 | ||
67 | The file commands check the return value from system calls and behave like for example the Tcl {\Tcl open} command, that is, they set the {\Tcl errorCode} variable to {\Tcl POSIX \emph{errno}}, e.g. {\Tcl POSIX ENOENT \{No such file or directory\}}. | |
68 | ||
69 | The code should be fairly robust, not just against user and programmer errors from `outside' (using the {\Tcl snacc} Tcl command), but against errors from the `inside' as well such as illegal numeric values for enumeration types or illegal choice settings as well. | |
70 | ||
71 | There are two types of errors: | |
72 | \begin{enumerate} | |
73 | \item programmer errors, where the program has no other choice as to print a regret to the user and exit | |
74 | \item user errors, such as trying to write to a read-only file, where the program should tell the user about their mistake and let them try something else. | |
75 | \end{enumerate} | |
76 | The Tcl interface code helps the programmer for the second type of error by setting Tcl's {\Tcl errorCode} variable. | |
77 | The program can {\Tcl catch} any error, and, based on the {\Tcl errorCode}, choose to deal with the mistake or rethrow the error that it is not prepared to handle. | |
78 | ||
79 | \subsection{File commands} | |
80 | ||
81 | Most snacc Tcl commands operate on so-called files. | |
82 | A file is an internal data structure that | |
83 | \begin{itemize} | |
84 | \item references the C++ representation of an ASN.1 data structure as a pointer to {\C AsnType} | |
85 | \item may be associated with an external file in the file system | |
86 | \end{itemize} | |
87 | ||
88 | The commands operating on these files are as follows: | |
89 | ||
90 | \begin{description}%{ | |
91 | \item[{\Tcl snacc create \emph{type}}] | |
92 | The command creates a file consisting only of an instance of type \emph{type}. | |
93 | \emph{type} has to be denoted as one argument, a Tcl list with two elements, module and type. | |
94 | No external filename is associated with this file. | |
95 | % The command returns a file handle that consists of letters and digits only and may therefore be used to construct a component in the Tk widget tree. | |
96 | ||
97 | \item[{\Tcl snacc open \emph{type filename} ?\emph{flags}? ?\emph{mode}?}] | |
98 | Open a file and read and decode its contents. | |
99 | \emph{type} has to be denoted as one argument, a list with two elements, module and type. | |
100 | The optional \emph{flags} may consist of: | |
101 | \begin{description} | |
102 | \item[{\Tcl create}] If the file does not exist, create it. | |
103 | If this flag is not given and the file does not already exist, an error occurs. | |
104 | \item[{\Tcl truncate}] If the file exists, drop its contents. | |
105 | \item[{\Tcl \emph{access}}] which may be either {\Tcl ro} or {\Tcl rw}, denoting read only and read/write access. | |
106 | If no access mode is specified, the file will be opened read/write if it is writable, and read only otherwise. | |
107 | \end{description} | |
108 | If the file is created, its mode is set to \emph{mode}, minus umask, of course. | |
109 | \emph{mode} may be any value accepted by {\C Tcl\_GetInt(3)} (the function accepts octal values). | |
110 | At last, if the file could be opened, its contents is read and BER decoded. | |
111 | As for {\Tcl snacc create} above, a file handle is returned. | |
112 | ||
113 | If the file cannot be opened, an error is returned identical to Tcl's {\Tcl open} command. | |
114 | ||
115 | More errors can be returned, as described under {\Tcl snacc read} below. | |
116 | ||
117 | \item[{\Tcl snacc close \emph{file}}] | |
118 | closes the file \emph{file} and invalidates the file handle. | |
119 | ||
120 | \item[{\Tcl snacc read \emph{file} ?\emph{type filename}?}] | |
121 | without the \emph{filename}, rereads the file from its old place; otherwise opens \emph{filename}, reads its contents into \emph{file} and closes it. | |
122 | The file's contents gets BER decoded. | |
123 | ||
124 | In case no \emph{filename} has been given but the \emph{file} is not associated with a filename, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC MUSTOPEN}. | |
125 | ||
126 | If Snacc's decoding routines detect an error, a Tcl error is returned and {\Tcl errorCode} is set to {\Tcl SNACC DECODE \emph{errval}} where \emph{errval} is the value returned by {\C setjmp()} (see sections~\ref{error-C++-section} and~\ref{lib-err-C-section} on pages~\pageref{error-C++-section} and~\pageref{lib-err-C-section}, respectively). | |
127 | ||
128 | If the input file is too short, the buffer will signal a read error and a Tcl error will be returned, with {\Tcl errorCode} set to {\Tcl SNACC DECODE EOBUF}. | |
129 | ||
130 | \item[{\Tcl snacc write \emph{file} ?\emph{filename}?}] | |
131 | BER encodes the file, then writes the file to its old place in case no \emph{filename} has been given, or opens \emph{filename}, writes \emph{file} into it and closes it. | |
132 | ||
133 | In case no \emph{filename} has been given but the \emph{file} is not associated with a filename, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC MUSTOPEN}. | |
134 | If you try to write to a read-only file, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC WRITE READONLY}. | |
135 | ||
136 | \item[{\Tcl snacc finfo \emph{file}}] | |
137 | returns a list with two elements, the file name associated with it (the empty string if no external file name is associated with it) and an identifier which may be | |
138 | \begin{description}%{ | |
139 | \item[{\Tcl bad}] the file is not associated with an external file. | |
140 | \item[{\Tcl rw}] the external file has been opened read/write. | |
141 | \item[{\Tcl ro}] the external file has been opened read only. | |
142 | \end{description}%} | |
143 | \end{description}%} | |
144 | ||
145 | Since Tcl cannot operate on binary strings (that is, strings containing NUL bytes), but ASN.1 octet strings may contain arbitrary binary data, the binary data has to be converted into a replacement notation that Tcl can work with and that can be converted back to binary without loss of information. | |
146 | The conversion I chose is fairly simple: NUL is converted into a backslash followed by a zero digit, and every backslash is doubled. | |
147 | ||
148 | These conversions for the most part take place automatically. | |
149 | In fact, there is only one point where the binary representation is necessary, when you want to read or write data from or into a file on disk. | |
150 | Two functions have been written to offer this: the export function converts and writes an octet string to an external file, and the import function reads binary data from a file and converts it to the Tcl compatible representation. | |
151 | Unlike the functions described above, these two do not operate on ASN.1 files, that is, the contents is not BER decoded/encoded, but may be used for any file in the file system. | |
152 | ||
153 | \begin{description}%{ | |
154 | \item[{\Tcl snacc import \emph{filename}}] opens the file named, reads its contents, closes it, performs the above described conversion and returns the resulting Tcl string. | |
155 | \item[{\Tcl snacc export \emph{string filename}}] converts the Tcl string into its binary counterpart, opens the file named, writes the binary buffer into it and closes it. | |
156 | The file is created and truncated as necessary. | |
157 | The command returns the empty string. | |
158 | \end{description}%} | |
159 | ||
160 | \subsection{Generic Information Retrieval} | |
161 | ||
162 | The following functions return information about the modules and their types. | |
163 | (This information is independent of any file instance, it is the information from the type descriptions in the {\ufn .asn1} files.) | |
164 | ||
165 | \begin{description}%{ | |
166 | \item[{\Tcl snacc modules}] | |
167 | returns a list of module identifiers. | |
168 | \item[{\Tcl snacc types ?\emph{module}?}] | |
169 | if a \emph{module} is specified, returns a list of all type names of that module. | |
170 | otherwise, a list of all types is returned as a list of pairs, where each pair consists of the module name and the type name. | |
171 | \item[{\Tcl snacc type \emph{type}}] | |
172 | where \emph{type} is a list with two elements, module and type. | |
173 | This command returns a list with the following four elements: | |
174 | \begin{enumerate}%{ | |
175 | \setcounter{enumi}{-1} | |
176 | \item the content type as a list consisting of module name and type name | |
177 | \item an identifier that is either {\Tcl pdu} or {\Tcl sub} depending on the list of PDUs that had been given after snacc's {\ufn -tcl} option. | |
178 | \item the ASN.1 type (e.g. INTEGER or CHOICE) | |
179 | \item a list of items that depends on the ASN.1 type: | |
180 | \begin{description}%{ | |
181 | \item[INTEGER] a (possibly empty) list of pairs of name and value for each named value. | |
182 | \item[ENUMERATED] a (non-empty) list of names. | |
183 | \item[SET, SEQUENCE \textnormal{and} CHOICE] a list of lists of four elements similar to that being described here. | |
184 | Element~0 is the subtypes name, then follow content type (a pair consisting of module name and type name), \emph{pdu} vs. \emph{sub} and finally the ASN.1 type. | |
185 | (The fourth element of the outer list is omitted for obvious reasons: it would explode the type's description.) | |
186 | \end{description}%} | |
187 | \end{enumerate}%} | |
188 | \end{description}%} | |
189 | ||
190 | \subsection{Operations on Content and Structure} | |
191 | ||
192 | Finally, the last last four functions operate on the file instances itself. | |
193 | All four commands get a \emph{path} argument that is constructed as follows: | |
194 | \begin{itemize} | |
195 | \item Every \emph{path} starts with a file handle as returned by {\Tcl snacc create} or {\Tcl snacc open}. | |
196 | \item All subsequent path elements, except for the last, must indicate elements of composed types. | |
197 | For CHOICE, SET and SEQUENCE, these are member names, for SET OF and SEQUENCE OF, these are numeric indices. | |
198 | \item The last path element may reference a simple type. | |
199 | \item For SET OF and SEQUENCE OF, instead of a numeric index, a pair consisting of the word {\Tcl insert} followed by a numeric index may be specified. | |
200 | In this case, a new list element is inserted before that addressed by the index. | |
201 | The index must be in the range $0\ldots{}n-1$ to address existing elements and it must be in the range $0\ldots{}n$ for insertion, where in both cases $n$ is the number of elements in the list. | |
202 | \item For {\Tcl snacc unset}, the path must point to an optional member of a SET or SEQUENCE or to an element of a SET OF or SEQUENCE OF. | |
203 | \end{itemize} | |
204 | ||
205 | The commands are: | |
206 | \begin{description}%{ | |
207 | \item[{\Tcl snacc info \emph{path}}] returns information about the value pointed to by \emph{path}. | |
208 | The information returned is quite similar to that of {\Tcl snacc type} above, with the following exceptions: | |
209 | \begin{itemize}%{ | |
210 | \item element~0, the content type, contains empty names for types that have not been given a name (e.g. a SET member of type OCTET STRING | |
211 | Example: the {\ASN contents} member in type {\ASN File} in file {\ufn edex1.asn1} (page~\pageref{edex1.asn1}) {\Tcl snacc info} returns {\Tcl \{\{\} \{\}\} sub \{OCTET STRING\}}). | |
212 | \item the number of elements depends on the ASN.1 type: | |
213 | \begin{description}%{ | |
214 | \item simple types (\textbf{NULL}, \textbf{BOOLEAN}, \textbf{INTEGER}, \textbf{ENUMERATED}, \textbf{REAL}, \textbf{BIT STRING} and \textbf{OCTET STRING}): | |
215 | no additional elements are returned. | |
216 | For the list of named values for INTEGER, ENUMERATED and BIT STRING, you have to call {\Tcl snacc type [lindex [snacc info \emph{path}]~0]}, unless the content type equals {\Tcl \{\{\}~\{\}\}}. | |
217 | \item[CHOICE] | |
218 | a total of five elements is returned, number~3 is the name of the choice member currently chosen, and the final element number~4 is an identifier that is either {\Tcl void} or {\Tcl valid} depending on whether the pointer representing the choice member is {\C NULL} or pointing to some data. | |
219 | \item[SET \textnormal{and} SEQUENCE] | |
220 | a fourth element, a list of pairs, is returned, where the pairs are built from the member name and an identifier that is either {\Tcl valid} or {\Tcl void} | |
221 | \item[SET OF \textnormal{and} SEQUENCE OF] | |
222 | the number of items is returned as element number~3. | |
223 | \end{description}%} | |
224 | \end{itemize}%} | |
225 | \item[{\Tcl snacc get \emph{path}}] | |
226 | returns the value of the subtree pointed to by \emph{path}. | |
227 | The value returned is a simple string for simple types, and a hierarchical structure (in Tcl that is a list of lists) otherwise. | |
228 | \begin{description}%{ | |
229 | \item[NULL] | |
230 | the empty string is returned. | |
231 | \item[BOOLEAN] | |
232 | the value is returned as {\Tcl TRUE} or {\Tcl FALSE}. | |
233 | \item[INTEGER] | |
234 | the numeric value is returned, even if it has been assigned a name. | |
235 | \item[ENUMERATED] | |
236 | the symbolic value is returned. | |
237 | The numeric values are inaccessible through the Tcl interface. | |
238 | If the object happens to contain an illegal numeric value, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC ILLENUM}. | |
239 | \item[REAL] | |
240 | the value is returned as formatted by {\C sprintf (\dots, "\%g", \dots)}, except for the special values {\ASN PLUS-INFINITY} and {\ASN MINUS-INFINITY} which are returned as {\Tcl +inf} and {\Tcl -inf}, respectively. | |
241 | \item[BIT STRING] | |
242 | a string, consisting solely of `0' and `1', is returned. | |
243 | \item[OCTET STRING] | |
244 | the binary string is returned as is, except for the unavoidable NUL-escape described above. | |
245 | \item[OBJECT IDENTIFIER] | |
246 | the value is returned as a list of numbers. | |
247 | \item[CHOICE] | |
248 | is returned as a pair, the choice member chosen and its value. | |
249 | \item[SET \textnormal{and} SEQUENCE] | |
250 | are returned as a list of pairs of member name and value. | |
251 | Absent OPTIONAL members are left out from the list. | |
252 | \item[SET OF \textnormal{and} SEQUENCE OF] | |
253 | are returned as a list of values. | |
254 | \end{description}%} | |
255 | \item[{\Tcl snacc set \emph{path value}}] sets the subtree identified by \emph{path} to \emph{value}. | |
256 | The value must be of the form | |
257 | \begin{description}%{ | |
258 | \item[NULL] | |
259 | the only legal value is the empty string. | |
260 | otherwise, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC ILLNULL}. | |
261 | \item[BOOLEAN] | |
262 | any value that is accepted by {\C Tcl\_GetBoolean}(3) is fine. | |
263 | \item[INTEGER] | |
264 | both the numeric (as accepted by {\C Tcl\_GetInt(3)}) and the symbolic values are allowed. | |
265 | \item[ENUMERATED] | |
266 | any value must be specified by its name. | |
267 | If an illegal name is given, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC ILLENUM}. | |
268 | \item[REAL] | |
269 | the special values {\ASN PLUS-INFINITY} and {\ASN MINUS-INFINITY} have to be given as {\Tcl +inf} and {\Tcl -inf}, respectively. | |
270 | All other values may be specified in any format accepted by {\C Tcl\_GetDouble}(3). | |
271 | \item[BIT STRING] | |
272 | a string that must consist of `0' and `1' only has to be given. | |
273 | otherwise, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC ILLBIT}. | |
274 | \item[OCTET STRING] | |
275 | due to the NUL-escapes necessary, any string where a backslash is followed by either another backslash or a `0' digit is legal. | |
276 | Improper use of the escape character leads to an error and {\Tcl errorCode} will be set to {\Tcl SNACC ILLESC}. | |
277 | \item[OBJECT IDENTIFIER] | |
278 | the value has to be specified as a list of numbers. | |
279 | if the arc has less than 2 or more than 10 elements, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC ILLARC <2} or {\Tcl SNACC ILLARC >10}, respectively. | |
280 | \item[CHOICE] | |
281 | the value expected is a pair, the choice member chosen and its value. | |
282 | if an illegal member is specified, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC ILLCHOICE}. | |
283 | \item[SET \textnormal{and} SEQUENCE] | |
284 | the value has got to be a list of pairs of member name and value. | |
285 | Any member may be specified at most once. | |
286 | All mandatory members must be present. | |
287 | Failure to do so will result in an error and {\Tcl errorCode} to be set to {\Tcl SNACC DUPMEMB} or {\Tcl SNACC MISSMAND}, respectively. | |
288 | All optional members not listed in the value will be deallocated. | |
289 | \item[SET OF \textnormal{and} SEQUENCE OF] | |
290 | the whole list is replaced with the specified value that has to be a proper Tcl list. | |
291 | \end{description}%} | |
292 | \item[{\Tcl snacc unset \emph{path}}] | |
293 | unsets the subtree pointed to by \emph{path}. | |
294 | Only OPTIONAL members of SET and SEQUENCE types and list elements of SEQ OF and SEQUENCE OF may be unset. | |
295 | If you try to unset a mandatory SET or SEQUENCE member, an error is returned and {\Tcl errorCode} is set to {\Tcl SNACC MANDMEMB}. | |
296 | \end{description}%} | |
297 | ||
298 | I did not follow Tk's example where one has to set widget commands to {\Tcl \{\}} to delete them. | |
299 | This method would have the drawback that one could not distinguish between an empty and a non-existing octet string (in C that would be {\C ""} vs. {\C NULL}). | |
300 | ||
301 | The value returned by {\Tcl snacc get} may be very long, {\Tcl snacc get file0} returns the contents of the whole file! | |
302 | ||
303 | \section{\label{snacc-examples}Examples} | |
304 | ||
305 | The following example session shall illustrate the {\Tcl snacc} commands usage. | |
306 | It assumes that the editor example files {\ufn edex0.asn1} and {\ufn edex1.asn1} (see appendix~\ref{edex-files} on page~\pageref{edex-files}) have been compiled into a binary that has been linked with the necessary libraries. | |
307 | ||
308 | The notation used is as in the Tcl book \cite{tcl-book}, i.e. `$\Rightarrow$' indicates a normal return value and `$\varnothing$' indicates an error with the error message set in {\Tcl \emph{oblique typeface}}. | |
309 | ||
310 | A look at the types available: | |
311 | ||
312 | \begin{Tclex} | |
313 | & snacc types\\ | |
314 | \R & \{EdEx-Simple Hand\} \{EdEx-Structured StructuredChoice\} \{EdEx-Structured Coordinate\} \{EdEx-Structured CoordinateSeq\} \{EdEx-Structured RGBColor\} \{EdEx-Structured Simple\} \{EdEx-Simple File\} \{EdEx-Simple RainbowColor\} \{EdEx-Structured DirectorySetOf\} \{EdEx-Structured Various\} \{EdEx-Structured File1\} \{EdEx-Structured CoordinateSeq1\} \{EdEx-Structured Directory\} \{EdEx-Structured Structured\} \{EdEx-Simple DayOfTheWeek\} | |
315 | \end{Tclex} | |
316 | ||
317 | Create a file (without filename): | |
318 | ||
319 | \begin{Tclex} | |
320 | & set file [snacc create \{EdEx-Structured Structured\}]\\ | |
321 | \R & file0 | |
322 | \end{Tclex} | |
323 | ||
324 | The string returned is the file handle. It is used as the first snaccpath component in successive calls. | |
325 | ||
326 | Look at the file's type: | |
327 | ||
328 | \begin{Tclex} | |
329 | & snacc info \$file\\ | |
330 | \R & \{EdEx-Structured Structured\} sub SET \{\{coord valid\} \{color valid\}\} | |
331 | \end{Tclex} | |
332 | ||
333 | The file's type is a SET with the name `Structured' in module `EdEx-Structured' (it is defined in file {\ufn edex1.asn1} (see page~\pageref{edex1.asn1})). | |
334 | The `sub' tells us that the type has not been marked as a PDU. | |
335 | The SET has the components `coord' and `color', both are present (they are not OPTIONAL, i.e. mandatory). | |
336 | ||
337 | Look at a component's type: | |
338 | ||
339 | \begin{Tclex} | |
340 | & snacc info "\$file color"\\ | |
341 | \R & \{EdEx-Structured StructuredChoice\} sub CHOICE rainbow valid | |
342 | \end{Tclex} | |
343 | ||
344 | Snacc has generated the type name `StructuredChoice' for this type, this name was not defined in the {\ufn .asn1} file. | |
345 | The CHOICE object currently is set to `rainbow'. | |
346 | A CHOICE component is always present (CHOICE components may not be OPTIONAL), the `valid' is just for completeness. | |
347 | ||
348 | Ask for the CHOICE's generic type information: | |
349 | ||
350 | \begin{Tclex} | |
351 | & snacc type \{EdEx-Structured StructuredChoice\}\\ | |
352 | \R & \{EdEx-Structured StructuredChoice\} sub CHOICE \{\{rainbow \{EdEx-Simple RainbowColor\} sub INTEGER\} \{rgb \{EdEx-Structured RGBColor\} sub SEQUENCE\}\} | |
353 | \end{Tclex} | |
354 | ||
355 | The CHOICE type has two possible components, `rainbow', an INTEGER and `rgb', a SEQUENCE. | |
356 | ||
357 | Look at the INTEGER's type information: | |
358 | ||
359 | \begin{Tclex} | |
360 | & snacc type \{EdEx-Simple RainbowColor\}\\ | |
361 | \R & \{EdEx-Simple RainbowColor\} sub INTEGER \{\{red~0\} \{orange~1\} \{yellow~2\} \{green~3\} \{blue~4\} \{indigo~5\} \{violet~6\}\} | |
362 | \end{Tclex} | |
363 | ||
364 | The type has got named values. | |
365 | ||
366 | Access the file contents: | |
367 | ||
368 | \begin{Tclex} | |
369 | & snacc get \$file\\ | |
370 | \R & \{coord \{cartesian \{\{x 0\} \{y 0\}\}\}\} \{color \{rainbow 977768\}\} | |
371 | \end{Tclex} | |
372 | ||
373 | The color component contains garbage. | |
374 | Change that: | |
375 | ||
376 | \begin{Tclex} | |
377 | & snacc set "\$file color rainbow" green\\ | |
378 | \R &\\ | |
379 | & snacc get "\$file color"\\ | |
380 | \R & rainbow 3 | |
381 | \end{Tclex} | |
382 | ||
383 | Change it again, select the CHOICE's other component type, `rgb', and set its `red' component: | |
384 | ||
385 | \begin{Tclex} | |
386 | & snacc set "\$file color rgb red" 256\\ | |
387 | \R & | |
388 | \end{Tclex} | |
389 | ||
390 | Changing a CHOICE component selection work only for write access, on read access this is not possible: | |
391 | ||
392 | \begin{Tclex} | |
393 | & snacc get "\$file color rainbow"\\ | |
394 | \E & \emph{snacc get: illegal component "rainbow" in path}\\ | |
395 | & snacc get "\$file color rgb"\\ | |
396 | \R & \{red 256\} \{green 544501616\} \{blue 1814045815\} | |
397 | \end{Tclex} | |
398 | ||
399 | Upon setting a SET or SEQUENCE type, all mandatory members have to be specified: | |
400 | ||
401 | \begin{Tclex} | |
402 | & snacc set "\$file color rgb" \{\{green 0\} \{blue 0\}\}\\ | |
403 | \E & \emph{mandatory member "red" is missing in list}\\ | |
404 | & snacc set "\$file color rgb" \{\{red 0\} \{green 256\} \{blue 0\}\}\\ | |
405 | \R &\\ | |
406 | & snacc get "\$file color"\\ | |
407 | \R & rgb \{\{red 0\} \{green 256\} \{blue 0\}\} | |
408 | \end{Tclex} | |
409 | ||
410 | Finish up: | |
411 | ||
412 | \begin{Tclex} | |
413 | & snacc close \$file\\ | |
414 | \R &\\ | |
415 | & snacc get \$file\\ | |
416 | \E & \emph{snacc get: no file named "file0"} | |
417 | \end{Tclex} | |
418 | ||
419 | \section{\label{tcl-if-impl}Implementation} | |
420 | ||
421 | The Tcl interface is implemented in {\ufn \dots/c++-lib/inc/tcl-if.h} and {\ufn \dots/c++-lib/src/tcl-if.C}. | |
422 | It gets initialized with the help of {\ufn \dots/c++-lib/inc/init.h} and {\ufn \dots/c++-lib/src/tkAppInit.c}. | |
423 | ||
424 | The {\Tcl snacc} commands implementation is pretty straight forward: check the arguments, call a metacode function to perform an action and return the result, which may indicate success or an error. | |
425 | ||
426 | Care has been taken to check the return codes of all system calls and to set Tcl's {\Tcl errorCode} variable in case any system call returns an error. | |
427 | ||
428 | The file {\ufn tkAppInit.c} contains the function that introduces the {\Tcl snacc} Tcl command to the Tcl interpreter. | |
429 | The path that leads to the function's invocation is a little tricky and is described in section~\ref{editor-building}, ``Building Your Own Editor''. | |
430 | ||
431 | \section{Setup for the Tcl Code Generator} | |
432 | ||
433 | To compile Snacc with the Tcl interface code generator, you have got to fulfill the following conditions: | |
434 | \begin{itemize} | |
435 | \item the configure script must be able to find {\ufn tclsh} and the Tcl/Tk libraries | |
436 | \item the preprocessor switches {\C NO\_META} and {\C NO\_TCL} in {\ufn \dots/policy.h} must not be set | |
437 | \end{itemize} | |
438 | ||
439 | \section{\label{tcl-if-deficiencies}Deficiencies} | |
440 | ||
441 | \begin{itemize} | |
442 | \item | |
443 | Values defined in the ASN.1 files currently are inaccessible. | |
444 | Adding access functions to the metacode and Tcl interface is rather trivial: build an array of elements that hold a variable's name as a character string and an {\C AsnType~*} that points to the C++ variable. | |
445 | {\C a[i].val-->\_getdesc()} would return a pointer to the variable's type description. | |
446 | ||
447 | (First you should fix snacc's value parser as currently it lets some values silently vanish, for example the {\ASN victory} in {\ufn edex0.asn1} that you can find in appendix~\ref{edex0.asn1} on page~\pageref{edex0.asn1}.) | |
448 | \item | |
449 | The Tcl interface does not provide symbolic object identifiers. | |
450 | Mapping numeric to symbolic oids is a task that is difficult to get right since snacc translates\\ | |
451 | {\ASN anOidVal OBJECT IDENTIFIER ::= \{ 1 2 foo(3) \}}\\ | |
452 | and\\ | |
453 | {\ASN anOidVal OBJECT IDENTIFIER ::= \{ 1 2 3 \}\\ | |
454 | foo INTEGER ::= 3}\\ | |
455 | into identical C++ code, but translating the second {\ASN anOidVal} into {\ASN \{ 1 2 foo \}} may in fact violate {\ASN foo}'s semantics. | |
456 | \end{itemize} |