]> git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/doc/c-gen.tex
Security-54.1.tar.gz
[apple/security.git] / SecuritySNACCRuntime / doc / c-gen.tex
1 % file: .../doc/c-gen.tex
2
3 % $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/doc/c-gen.tex,v 1.1.1.1 2001/05/18 23:14:10 mb Exp $
4 % $Log: c-gen.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:51 aram
9 % Originals from SMIME Free Library.
10 %
11 % Revision 1.1 1997/01/01 22:47:33 rj
12 % first check-in
13 %
14
15 \chapter{\label{c-code-gen-chapter}C Code Generation}
16 \section{\label{intro-C-section}Introduction}
17 Snacc was designed primarily to provide high-performance encoders and
18 decoders. Key areas to optimize are buffer and memory management.
19 Buffers are used to hold encoded values and the memory management is
20 used when building the internal representation of a value when decoding.
21
22 C macros are used where possible to eliminate function call overhead
23 for small, commonly used routines. Using macros with constant
24 expressions as parameters allows smarter C compilers to do some of the
25 calculations at compile time. In general, short-cuts that can be taken
26 without sacrificing the robustness of code are used.
27
28 The generated code can be quite large; large reductions of the size of
29 the binaries can be achieved by using the optimizing options of your C
30 compiler.
31
32 We will use an example ASN.1 module, EX1, to help explain snacc's code
33 generation. The EX1 module uses some of the common built-in types and
34 contains some simple values. The field names have been left out
35 to show snacc naming conventions. The C generation code is in
36 {\ufn \dots/compiler/back-ends/c-gen/} if you want to alter it.
37
38 \begin{small}
39 \begin{verbatim}
40 EX1 DEFINITIONS ::=
41 BEGIN
42
43 anOidVal OBJECT IDENTIFIER ::= { joint-iso-ccitt 40 foobar(29) }
44 theSameOidVal OBJECT IDENTIFIER ::= { 2 40 29 }
45 anIntVal INTEGER ::= 1
46 aBoolVal BOOLEAN ::= TRUE
47
48 T1 ::= SEQUENCE
49 {
50 INTEGER OPTIONAL,
51 OCTET STRING OPTIONAL,
52 ENUMERATED { a(0), b(1), c(2) },
53 SEQUENCE OF INTEGER,
54 SEQUENCE { id OBJECT IDENTIFIER, value OCTET STRING },
55 CHOICE { INTEGER, OBJECT IDENTIFIER }
56 }
57
58 END
59 \end{verbatim}
60 \end{small}
61
62 \noindent
63 Use the following command to compile the EX1 ASN.1 module:
64
65 \noindent
66 {\ufn \%1 snacc -u \dots/asn1specs/asn-useful.asn1 \dots/asn1specs/ex1.asn1}
67 \noindent
68
69 This produces the files {\ufn ex1.h} and {\ufn ex1.c}.
70
71 For each ASN.1 type an equivalent C data type, a BER encoding routine,
72 a BER decoding routine, a printing routine and a freeing routine will
73 be generated. C values will also be generated from simple ASN.1
74 values. Each aspect of the C code generation will be discussed in the
75 next sections.
76
77 \section{\label{naming-C-section}ASN.1 to C Naming Conventions}
78
79 For any given module, snacc may produce C type definitions, functions
80 and {\C \#define}s. We assume that all C {\C typedef},
81 {\C struct}, {\C enum} and {\C union} tag, {\C enum} value,
82 variable, {\C \#define} and function names share a single name space.
83
84 The C type name for a type is the same as its ASN.1 type name (with
85 any hyphens converted to underscores) unless there is a conflict.
86 Since, unlike ASN.1, the C types for each ASN.1 module share the same
87 name space, snacc makes sure the C typenames are unique amoung all the
88 modules and that they do not conflict with C keywords. The conflicts
89 are resolved by appending digits to the conflicting name. To avoid
90 confusing numbered type names etc., you should edit the ASN.1 source
91 and name them properly.
92
93 Named numbers, ENUMERATED values and named bits are put in entirely in
94 upper case to match the common C convention for {\C \#define} and
95 {\C enum} values.
96
97 Empty field names in SETs, SEQUENCEs, and CHOICEs will be filled. The
98 field name is derived from the type name for that field. The library
99 types such as INTEGER have default field names defined by the compiler
100 (see {\ufn \dots/compiler/back-ends/c-gen/rules.c} and
101 {\ufn \dots/compiler/back-ends/c++-gen/rules.c}). The first letter of the field
102 name is in lower case. Again, empty field names should be fixed
103 properly by adding them to the ASN.1 source.
104
105 New type definitions will be generated for SETs, SEQUENCEs, CHOICEs,
106 ENUMERATED, INTEGERs with named numbers and BIT STRING with named bits
107 whose definitions are embedded in other SET, SEQUENCE, SET OF,
108 SEQUENCE OF, or CHOICE definitions. The name of the new type is
109 derived from the name of the type in which it was embedded. Perhaps a
110 better way would use the field name as well, if present.
111
112 \section{\label{type-gen-C-section}ASN.1 to C Data Structure Translation}
113
114 To handle the different scoping rules between ASN.1 and C, the names
115 of some ASN.1 data structure elements such as ENUMERATED type symbols
116 may be altered to avoid conflicts. The T1 type in example ASN.1
117 module EX1 has no field names so snacc will generate them. It is
118 recommended to provide field names in the ASN.1 source instead of
119 relying on compiler generated names. The following is the generated C
120 data structure for the EX1 module from the {\ufn ex1.h} file (function
121 prototypes have been removed):
122
123 \begin{small}
124 \begin{verbatim}
125
126 typedef enum
127 {
128 A = 0,
129 B = 1,
130 C = 2
131 } T1Enum; /* ENUMERATED { A(0), B(1), C(2) } */
132
133 typedef struct T1Choice /* CHOICE */
134 {
135 enum T1ChoiceChoiceId
136 {
137 T1CHOICE_INT1,
138 T1CHOICE_OID
139 } choiceId;
140 union T1ChoiceChoiceUnion
141 {
142 AsnInt int1; /* INTEGER */
143 AsnOid *oid; /* OBJECT IDENTIFIER */
144 } a;
145 } T1Choice;
146
147 typedef struct T1Seq /* SEQUENCE */
148 {
149 AsnOid id; /* OBJECT IDENTIFIER */
150 AsnOcts value; /* OCTET STRING */
151 } T1Seq;
152
153 typedef AsnList T1SeqOf; /* SEQUENCE OF INTEGER */
154
155 typedef struct T1 /* SEQUENCE */
156 {
157 AsnInt *int1; /* INTEGER OPTIONAL */
158 AsnOcts octs; /* OCTET STRING OPTIONAL */
159 T1Enum t1Enum; /* T1Enum */
160 T1SeqOf *t1SeqOf; /* T1SeqOf */
161 struct T1Seq *t1Seq; /* T1Seq */
162 struct T1Choice *t1Choice; /* T1Choice */
163 } T1;
164 \end{verbatim}
165 \end{small}
166
167 Every ASN.1 type definition maps into a C {\C typedef}. SETs and
168 SEQUENCEs map into C structures and other simple types map into their
169 obvious C counterpart. SET OF and SEQUENCE OF types map into a
170 generic list type which is doubly linked and NULL terminated. The
171 reverse link on the lists allows for simpler backwards encoding. More
172 information on the library types can be found in Chapter~\ref{lib-C-chapter}.
173
174 Comments that contain a fragment of each type's ASN.1 definition are
175 inserted in the header file to clarify cases where elements have been
176 re-named.
177
178 Aggregate types that are defined in other type definitions are moved
179 to their own type definitions. For example, notice how the SEQUENCE
180 and CHOICE that are in type {\C T1} have been moved to the types
181 {\C T1Seq} and {\C T1Choice} in the C code. This simplifies code
182 generation at the cost of introducing new types.
183
184 Identifiers for named numbers from INTEGER and ENUMERATED types and
185 named bits from the BIT STRING type are capitalized in the C
186 representation. The ENUMERATED type maps to a C {\C enum} and the INTEGER
187 and BIT STRING named numbers/bits are handled with {\C \#define}
188 statements.
189
190 Most OPTIONAL elements of SEQUENCEs and SETs are referenced by
191 pointer. An element is considered present if its pointer is non-NULL\@.
192 OCTET STRINGs, BIT STRINGs and OBJECT IDENTIFIERs are the exceptions,
193 and are included by value even when they are OPTIONAL because they are
194 small and contain an internal pointer that can be used to determine
195 their presence. For an example of this, look at the first two
196 elements of type {\C T1}. The INTEGER type is referenced by pointer
197 because it is OPTIONAL, but the OCTET STRING type is included
198 (non-pointer) in the {\C T1} type even though it is OPTIONAL\@.
199
200
201 \section{\label{encode-gen-C-section}Encode Routines}
202
203 Snacc generates two kinds of encoding routines. One is PDU oriented
204 and encodes the type's tag, length and content and the other
205 only encodes the type's content. The generated encoders only call the
206 content encoders, except in the case of ANY and ANY DEFINED BY types.
207 Typically, you will only call the PDU oriented routines from your
208 code.
209
210 The content and PDU encoding routine interfaces are similar for all
211 ASN.1 types. They both take two parameters, one is a buffer pointer
212 and the other is a pointer to the value to be encoded. For example
213 the {\C T1} type from module EX1 has the following prototypes for
214 its encoding routines.
215
216 \begin{verbatim}
217 AsnLen BEncT1Content (BUF_TYPE b, T1 *v);
218 AsnLen BEncT1 (BUF_TYPE b, T1 *v);
219 \end{verbatim}
220
221 {\C BEnc} is short for ``BER Encode''. The {\C BUF\_TYPE}
222 parameter is the buffer to encode the value into and the {\C T1~*}
223 parameter is a pointer to the instance of the {\C T1} type that is to be
224 encoded.
225
226 The {\C BEncT1Content} routine only encodes the content of a {\C T1}
227 type and returns its encoded length; it does not encode its tag
228 (UNIVERSAL (CONSTRUCTED) 16 for SEQUENCE) or length. The job of
229 encoding the tag and length is up to any type that encapsulates {\C T1}.
230 This design allows decisions about implicit tagging to be made at code
231 generation time instead of runtime, improving performance. Also,
232 different encoding rules may fit into this model more easily.
233
234 The {\C BEncT1} routine encodes the tag (UNIVERSAL (CONSTRUCTED) 16
235 for SEQUENCE), length and content of a {\C T1} type and returns its encoded
236 length. This is the PDU oriented routine and will only be generated
237 if the user designates the type as a PDU type via a compiler directive
238 or the type is used as
239 the content of an ANY or ANY DEFINED BY type (as indicated by an
240 OBJECT-TYPE macro). A PDU type is a type that defines an entire PDU;
241 the user will typically be calling the encode and decode routine for
242 PDU types directly. See Section~\ref{compiler-dir-C-section} for how to
243 designate PDU types with compiler directives.
244
245 The snacc encoders are somewhat strange; they encode a value starting
246 from the end of its BER representation and work back to its beginning.
247 This ``backwards'' encoding technique simplifies the use of definite
248 lengths on constructed values. Other encoders that encode forwards,
249 such as those of CASN1, use an intermediate buffer format so that a
250 buffer containing the encoded length of a constructed value can be
251 inserted before its encoded content, after the content has been
252 encoded. Use of intermediate buffers hurts performance. Other
253 compilers' approaches have been to only encode indefinite lengths for
254 constructed values, however, this will not support some encoding rules
255 such as DER\@. The drawback of encoding backwards is that BER values
256 cannot be written to stream-oriented connections as they are encoded.
257
258 Both definite and indefinite length encodings for constructed values'
259 lengths are supported. Currently the choice is made when compiling
260 the generated code, via the {\C USE\_INDEF\_LEN} flag. If both length
261 forms, definite and indefinite, are required, it easy to modify the
262 length encoding macros to check a global variable for the length
263 form to use. For most types, using definite lengths produces smaller
264 encodings with little performance difference.
265
266 After calling an encode routine you should always check the buffer
267 you encoded into for a write error. This is the only error reporting
268 mechanism used for the encoders. See the C buffer section (Section
269 \ref{lib-buf-section}) for how to check a buffer for a write error.
270
271
272 \section{\label{decode-gen-C-section}Decode Routines}
273
274 Decoding routines are like the encoding routines in that there are two
275 kinds, one that decodes the type's tag, length and content and one
276 that only decodes the type's content. As mentioned in the encoder
277 section, the content style interface allows implicit tagging decisions
278 to be made at compile time.
279
280 Unlike the encoding routines, the PDU and content decoding routines
281 take different arguments. For the {\C T1} type the following would be
282 produced:
283 \begin{verbatim}
284 void BDecT1Content (BUF_TYPE b, AsnTag tagId0, AsnLen elmtLen0, T1 *v, AsnLen *bytesDecoded, ENV_TYPE env);
285 void BDecT1 (BUF_TYPE b, T1 *v, AsnLen *bytesDecoded, ENV_TYPE env);
286 \end{verbatim}
287
288 Notice that the content decoder, {\C BDecT1Content}, has tag and
289 length parameters that the PDU decoder, {\C BDecT1}, does not have.
290 Since the content decoder does not decode the tag and length on the
291 value, it is necessary to pass them in as parameters. Only OCTET
292 STRING and BIT STRING decoders will actually use the information
293 in the tag parameter.
294
295 The {\C BUF\_TYPE} parameter is the buffer that holds the BER value
296 being decoded.
297
298 The {\C tagId0} parameter is the last tag that was decoded on the
299 content of the type that is about to be decoded. In the case of type
300 {\C T1}, {\C BDecT1Content} gets a tagId0 of UNIVERSAL (CONSTRUCTED) 16,
301 unless it is implicitly tagged by another type. Most content decoding
302 routines ignore the tag information. OCTET STRING and BIT STRING
303 decoders use the tag information to determine whether the contents are
304 constructed or primitive. CHOICE decoders use the tag information to
305 determine which CHOICE element is present. CHOICE values are treated
306 differently, as will be explained shortly.
307
308 The {\C elmtLen0} parameter is the length of the content of the type
309 being decoded. This is simply the length decoded from the buffer by
310 the containing type's decoder just before calling this decode routine.
311
312 The {\C v} parameter is a pointer to space allocated for the type
313 being decoded. This memory is not allocated by the decoding routine
314 itself; this supports the cases where the type is enclosed in the
315 struct of the parent (i.\,e.\ no extra allocation is necessary). If
316 the type to be decoded is referenced by pointer from its parent type,
317 the parent type's decoding routine must allocate the type.
318
319 The {\C bytesDecoded} parameter maintains the running total of the
320 number of octets that have been decoded. For example, if I call
321 {\C BDecT1Content} with a {\C bytesDecoded} parameter that points
322 to 20 and the encoded length of the {\C T1} value is 30 octets,
323 {\C bytesDecoded} will point to 50 when {\C BDecT1Content}
324 returns. Maintaining the length is vital to determining the presence
325 or absence of OPTIONAL elements in a SET or at the end of SEQUENCE\@.
326 Local variables are used to hold the lengths; there is no global stack
327 of lengths as with CASN1.
328
329 The {\C env} parameter is used in conjunction with {\C longjmp}
330 calls. When an decoder encounters a fatal error such as a missing
331 tag, it uses the {\C env} with a {\C longjmp} call to pop back to the
332 initial decode call. Section~\ref{lib-err-C-section} has more error
333 management details.
334
335 CHOICEs are decoded a little differently from other types. For all
336 types except CHOICEs, all of the tag and length pairs on the content
337 are decoded by the parent type, and the last pair a passed into to
338 content decoding routine via the {\C tagId0} and {\C elmtLen0}
339 parameters. For CHOICEs, all of the tag and length pairs on the
340 content are decoded and then the first tag and length pair in the
341 CHOICE content is decoded by the parent and passed into the CHOICE
342 content decoding routine. The first tag in a CHOICE's content is the
343 important tag by which the CHOICE determines which element is present.
344 This technique simplifies the code for dealing with untagged CHOICEs
345 embedded in other CHOICEs. CHOICEs nested in this way mean that a
346 single tag determines which element is present in more than one
347 CHOICE\@.
348
349 The decoding routines allocate memory to hold the decoded value. By
350 default snacc decoders use nibble memory (see Section
351 \ref{lib-mem-C-section}) which is very efficient in allocation and
352 virtually cost free for freeing.
353
354 To save memory, decoders generated by some other tools build values
355 that reference the data in the encoded PDU for types like OCTET
356 STRING\@. Snacc decoded values do not reference the BER data in any way
357 for several reasons. One, the encoded value may be held in some
358 bizarre buffer making access to the value difficult. Two, with more
359 encoding rules being formalized, this technique may not always work
360 since the encoded format may be different from the desired internal
361 format. Three, snacc decoders concatenate any constructed BIT and
362 OCTET STRINGs values when decoding, to simplify processing in the
363 application.
364
365 Snacc decoders can detect a variety of errors which will be reported
366 by {\C longjmp}. Any tagging errors are reported. SETs must contain
367 all non-OPTIONAL components and SEQUENCEs must be in order and contain
368 all non-OPTIONAL components. Extra components in SETs and SEQUENCEs
369 are considered an error. Errors will also be reported if you attempt
370 to decode values that exceed the limitations of the internal
371 representation (e.\,g.\ an integer that is larger than a
372 {\C long int} allows).
373
374 \section{\label{print-gen-C-section}Print Routines}
375 All of the generated print routines take similar parameters. For
376 example the {\C T1} type's print routine prototype is:
377 \begin{verbatim}
378 void PrintT1 (FILE *f, T1 *v, unsigned short int indent);
379 \end{verbatim}
380
381 The print routine writes the given value, {\C v}, to the given {\C FILE~*},
382 {\C f}. The printed value is indented by {\C indent} spaces. The
383 values are printed in an ASN.1 value notation style. {\C PrintT1}
384 prints in the following style:
385 \begin{small}
386 \begin{verbatim}
387 { -- SEQUENCE --
388 17,
389 '436c696d6220617420537175616d697368'H -- "Climb at Squamish" --,
390 0,
391 { -- SEQUENCE OF --
392 18,
393 19
394 },
395 { -- SEQUENCE --
396 id {2 40 29},
397 value '736f6d6520737472696e67'H -- "some string" --
398 },
399 20
400 }
401 \end{verbatim}
402 \end{small}
403
404 OCTET STRINGs are printed in a hexadecimal notation, and any printable
405 characters are included after the string in an ASN.1 comment. Note
406 that the enumerated type value, 0, did not print its symbol, ``A''
407 from the ENUMERATED type. It would be fairly easy to modify the C and
408 C++ back ends to generate print routines that printed the ENUMERATED
409 types' symbols instead of their values.
410
411 \section{\label{free-gen-C-section}Free Routines}
412
413 Snacc generates free routines of the form:
414 \begin{verbatim}
415 void FreeT1 (T1 *v);
416 \end{verbatim}
417
418 These routines will free all the components named type.
419 For example the above {\C FreeT1} routine will free all the
420 components of the given {\C T1} value, but not the {\C T1} value itself. The
421 passed in pointer is not freed because it may be embedded in another
422 type which will be freed by another call to {\C Asn1Free}. All the pieces
423 of memory are freed using the {\C Asn1Free} macro defined in
424 {\ufn asn-config.h}. Each library type has its own free routine that
425 may call {\C Asn1Free}. The values are typically allocated during
426 decoding, using the {\C Asn1Alloc} macro.
427
428 The memory management can be changed by editing the {\ufn asn-config.h}
429 file to use you own memory management routines. By default the memory
430 manager uses the nibble memory system described in Section
431 \ref{lib-mem-C-section}. The nibble memory system does not need explicit
432 frees of each component so the generated free routines are not needed.
433 However, if you change the memory management to use something like
434 {\C malloc} and {\C free}, you should use the generated free routines.
435
436
437 \section{\label{val-gen-C-section}ASN.1 to C Value Translation}
438
439 C values will be produced for INTEGER, BOOLEAN and OBJECT IDENTIFIER
440 values. C {\C extern} declarations for the value are put at the end
441 of the header file (after all of the type definitions). The value
442 definitions are put at the beginning of the source file. For example,
443 the following will be produced for the EX1 module (at the end of
444 file ex1.h):
445
446 \begin{small}
447 \begin{verbatim}
448 extern AsnOid anOidVal;
449 extern AsnOid theSameOidVal;
450 extern AsnInt anIntVal;
451 extern AsnBool aBoolVal;
452 extern AsnInt foobar;
453 \end{verbatim}
454 \end{small}
455
456 (at the beginning of file ex1.c):
457
458 \begin{small}
459 \begin{verbatim}
460 AsnOid anOidVal = { 2, "\170\35" };
461 AsnOid theSameOidVal = { 2, "\170\35" };
462 AsnInt anIntVal = 1;
463 AsnBool aBoolVal = TRUE;
464 AsnInt foobar = 29;
465 \end{verbatim}
466 \end{small}
467
468 \section{\label{compiler-dir-C-section}Compiler Directives}
469
470 Snacc allows the user to control some aspects of the generated code by
471 inserting special comments in the ASN.1 source. Warning! only the
472 {\ASN isPdu} directive has been tested to any extent. Use the others
473 very carefully and only if you really need to. The compiler
474 directives have the form:
475
476 \begin{verbatim}
477 --snacc <attribute>:"<value>" <attribute>:"<value>" ...
478 \end{verbatim}
479
480 The {\ASN attribute} is the name of one of the accepted attributes and
481 the {\ASN value} is what the {\ASN attribute}'s new value will be.
482 The attribute value pairs can be listed in a single {\ASN --snacc}
483 comment or spread out in a list of consecutive comments.
484
485 Compiler directives are only accepted in certain places in the ASN.1
486 code. Depending on their location in the ASN.1 source, the compiler
487 directives affect type definitions or type references. The directives
488 for type definitions and references are different. Module level
489 compiler directives to specify output file names and other information
490 would be useful, but are not implemented.
491
492 Here is an example to present some of the compiler directives and
493 their uses. Let's say your data structure always deals with
494 {\C PrintableStrings} that are null terminated (internally, not in
495 the encoding). The default snacc string type is a structure that
496 includes a length and {\C char~*} for the string octets. To change
497 the default type to a simple {\C char~*} the best way would be define
498 your own string type, let's say {\ASN MyString} as follows:
499
500 \begin{small}
501 \begin{verbatim}
502 Foo ::= SET
503 {
504 s1 [0] MyString OPTIONAL,
505 s2 [1] MyString,
506 i1 [2] INTEGER
507 }
508
509 Bar ::= CHOICE
510 {
511 s1 MyString,
512 i1 INTEGER
513 }
514
515 Bell ::= MyString
516
517 MyString ::= --snacc isPtrForTypeDef:"FALSE"
518 --snacc isPtrForTypeRef:"FALSE"
519 --snacc isPtrInChoice:"FALSE"
520 --snacc isPtrForOpt:"FALSE"
521 --snacc optTestRoutineName:"MYSTRING_NON_NULL"
522 --snacc genPrintRoutine:"FALSE"
523 --snacc genEncodeRoutine:"FALSE"
524 --snacc genDecodeRoutine:"FALSE"
525 --snacc genFreeRoutine:"FALSE"
526 --snacc printRoutineName:"printMyString"
527 --snacc encodeRoutineName:"EncMyString"
528 --snacc decodeRoutineName:"DecMyString"
529 --snacc freeRoutineName:"FreeMyString"
530 PrintableString --snacc cTypeName:"char *"
531 \end{verbatim}
532 \end{small}
533
534 All but the last {\ASN --snacc} comment bind with the {\ASN MyString} type
535 definition. The last directive comment binds with the {\ASN PrintableString}
536 type. The C data structure resulting from the above ASN.1 and compiler
537 directives is the following:
538 \begin{small}
539 \begin{verbatim}
540 typedef char *MyString; /* PrintableString */
541
542 typedef struct Foo /* SET */
543 {
544 MyString s1; /* [0] MyString OPTIONAL */
545 MyString s2; /* [1] MyString */
546 AsnInt i1; /* [2] INTEGER */
547 } Foo;
548
549 typedef struct Bar /* CHOICE */
550 {
551 enum BarChoiceId
552 {
553 BAR_S1,
554 BAR_I1
555 } choiceId;
556 union BarChoiceUnion
557 {
558 MyString s1; /* MyString */
559 AsnInt i1; /* INTEGER */
560 } a;
561 } Bar;
562
563 typedef MyString Bell; /* MyString */
564 \end{verbatim}
565 \end{small}
566
567 The compiler directives used on the {\ASN MyString} type have some
568 interesting effects. Notice that {\ASN MyString} is not referenced by
569 pointer in the CHOICE, SET, or type definition, {\ASN Bell}.
570
571 The generated code for encoding field {\C s1} of {\C Foo} type
572 will use the code\linebreak``{\C MYSTRING\_NON\_NULL (\&fooVal-->s1)}'' to check
573 for the presence of the OPTIONAL {\C s1} field. The code associated
574 with MYSTRING\_NON\_NULL should return TRUE if the {\C s1} field
575 value is present and might look like:
576 \begin{verbatim}
577 #define MYSTRING_NON_NULL(s) (*s != NULL)
578 \end{verbatim}
579
580 The argument to {\C optTestRoutine} routine will be a pointer to the
581 field type's defining type. Note that in the above example,
582 {\ASN MyString} is a {\C char~*}, therefore the {\C MYSTRING\_NON\_NULL}
583 macro's argument will be a {\C char~**}.
584
585 Setting the {\ASN genPrintRoutine} etc. attributes to false makes
586 snacc not define or generate any encode, decode, print, or free
587 routines for the {\ASN MyString} type. You must provide these
588 yourself; the best approach is to take the normal {\ASN PrintableString}
589 routines and modify them to handle your special string type.
590
591 The names of the encode, decode, print and free routines used for the
592 {\ASN MyString} type will be based on the ones given with the
593 {\ASN printRoutineName} etc.\ attributes. Snacc will prepend a
594 ``B'' (for BER) and append a ``Content'' to the encode and decode
595 routines names, so you must provide the {\C BEncMyStringContent} and
596 {\C BDecMyStringContent} routines. You may also need the
597 {\C BEncMyString} and {\C BDecMyString} routines if {\ASN MyString} is a
598 PDU type or used in an ANY or ANY DEFINED type.
599
600 The {\ASN PrintableString} type has its C type name changed to
601 {\C char~*} by the last compiler directive. Thus {\ASN MyString} is defined
602 as a {\C char~*}. This directive applies to the {\ASN PrintableString}
603 type reference. Note that these directives do not affect the tags or
604 the encoded representation of the {\ASN MyString} type
605
606 The location of the {\ASN --snacc} comment(s) is important.
607 {\ASN --snacc} comment(s) between the {\ASN ::=} sign and the
608 following type are associated with the type being defined. Any
609 compiler directives after the type and before the next type or value
610 definition are associated with the type. Fields in SETs, SEQUENCEs
611 and CHOICEs can be modified by putting the compiler directive after
612 the comma that follows the field type that you wish to modify. In the
613 case of the last element of one of these types, where there is no
614 comma, just place it after the field and before the closing bracket of
615 the parent type.
616
617 Attributes shadow the type attributes filled in during the target
618 language type information generation pass of the compiler. The type
619 definition attributes are:
620
621 \begin{description}
622 \item[cTypeName] { this is the type name that the generated type will
623 have. Its value can be any string that is valid as a C type name.}
624
625 \item[isPdu] { whether this is a PDU type. A PDU type will have
626 extra interfaces to the encode and decode routines generated. Its
627 value can be ``TRUE'' or ``FALSE''}
628
629 \item[isPtrForTypeDef] { TRUE if other types defined solely by this type
630 definition are defined as a pointer to this type. Its
631 value can be ``TRUE'' or ``FALSE''.}
632
633 \item[isPtrForTypeRef]{ TRUE if type references to this type
634 definition from a SET or SEQUENCE are by pointer. Its
635 value can be ``TRUE'' or ``FALSE''.}
636
637 \item[isPtrInChoice] {TRUE if type references to this type definition
638 from a CHOICE are by pointer. Its value can be ``TRUE'' or ``FALSE''.}
639
640
641 \item[isPtrForOpt] { TRUE if OPTIONAL type references to this type
642 definition from a SET or SEQUENCE are by pointer. Its value can be
643 ``TRUE'' or ``FALSE''.}
644
645 \item[optTestRoutineName] {name of the routine to test whether an
646 OPTIONAL element of this type in a SET or SEQUENCE is present. The
647 routine should return TRUE if the element is present. The value of
648 this field is usually just the name of a C macro that tests for NON-NULL\@.
649 The argument to the routine will be a pointer to the type definition's
650 type. The optTestRoutineName value can be any string value.}
651
652 \item[defaultFieldName] { if this type is used in a SET, SEQUENCE or
653 CHOICE without a field name then this value is used with a digit
654 appended to it. Its value can be any string that is a valid C field
655 name in a struct or union.}
656 \item[printRoutineName] { name of this type definition's printing
657 routine. Its value can be any string that is a C function or
658 macro name.}
659 \item[encodeRoutineName]{ name of this type definition's encoding
660 routine. Its value can be any string that is a C function or
661 macro name.}
662 \item[decodeRoutineName]{ name of this type definition's decoding
663 routine. Its value can be any string that is a C function or
664 macro name.}
665 \item[freeRoutineName] { name of this type definition's freeing
666 routine. Its value can be any string that is a C function or
667 macro name.}
668
669 \item[isEncDec] {If this type is used in a SET or SEQUENCE then it is not
670 encoded or decoded. Its value can be ``TRUE'' or ``FALSE''. This is
671 handy for adding your own types to a standard that are only for local
672 use, and are not included in encoded values.}
673
674 \item[genTypeDef] { TRUE if you want a C type to be generated for this
675 type definition. Its values can be ``TRUE'' or ``FALSE''.}
676
677 \item[genPrintRoutine] { TRUE if you want a printing routine to be
678 generated for this type definition. Its values can be ``TRUE'' or
679 ``FALSE''.}
680 \item[genEncodeRoutine] { TRUE if you want an encoding routine to be
681 generated for this type definition. Its values can be ``TRUE'' or
682 ``FALSE''.}
683 \item[genDecodeRoutine] { TRUE if you want a decoding routine to be
684 generated for this type definition. Its values can be ``TRUE'' or
685 ``FALSE''.}
686 \item[genFreeRoutine] { TRUE if you want a free routine to be
687 generated for this type definition. Its values can be ``TRUE'' or
688 ``FALSE''.}
689 \end{description}
690
691
692 The type reference attributes are slightly different from the type
693 definition attributes due to the semantic differences between a type
694 definition and a type reference. Type references will inherit some of
695 their attributes from the referenced type definition. The following
696 are the valid type reference attributes:
697 \begin{description}
698 \item[cTypeName] { this is the type name that the generated type will
699 have. Its value can be any string that is valid as a C type name.}
700
701 \item[cFieldName] { if this is a field in a CHOICE, SET or SEQUENCE
702 then this holds the C field name for this reference. Its value can be
703 any string that is valid as a C field name.}
704
705 \item[isPtr] { TRUE if this is a pointer to the type named by
706 cTypeName. This is usually determined from the referenced type
707 definitions attributes. Its value can be ``TRUE'' or ``FALSE''.}
708
709 \item[optTestRoutineName] {if this field is an OPTIONAL component then
710 this is the name of the routine to test whether it is present. The
711 routine should return TRUE if the element is present. The value of
712 this is usually just the name of a C macro that tests for NULL\@. The
713 argument to the routine will be a pointer to the type definition's
714 type. The optTestRoutineName value can be any string value.}
715
716 \item[printRoutineName] { name of this type reference's printing
717 routine. This and the other routine name attributes are useful for
718 special instances of the referenced type. It is easier to modify the
719 referenced type definition if you want every instance of this type to
720 use a certain print etc.\ routine. Its value can be any string that is
721 a value C function or macro name.}
722
723 \item[encodeRoutineName]{ name of this type reference's encoding
724 routine. Its value can be any string that is a function or
725 macro name.}
726
727 \item[decodeRoutineName]{ name of this type reference's decoding
728 routine. Its value can be any string that is a C function or
729 macro name.}
730
731 \item[freeRoutineName] { name of this type reference's freeing
732 routine. Its value can be any string that is a C function or
733 macro name.}
734
735 \item[isEncDec] { If this type is used in a SET or SEQUENCE then the
736 field is not encoded or decoded. Its value can be ``TRUE'' or
737 ``FALSE''. This is handy for adding your own types to a standard that
738 are only for local use, and are not included in encoded values.}
739
740 \item[choiceIdSymbol] {if this is a component of a CHOICE, this string
741 attribute will be the defined/enum symbol whose value in the choiceId
742 field indicates the presence of this field.}
743 \item[choiceIdValue] {if this is a component of a CHOICE, this integer
744 attribute will be the value associated with the symbol in choiceIdSymbol.}
745
746 \end{description}
747
748
749
750
751 \section{\label{compiling-gen-C-section}Compiling the Generated C Code}
752
753 The generated C code (and libraries) can be compiled by both ANSI and K\&R C compilers.
754 C function prototypes use the {\C PROTO} macro and C function declarations use the {\C PARAMS} macro.
755 These macros are defined in {\ufn \dots/snacc.h} and their definitions depend on whether the {\C \_\_USE\_ANSI\_C\_\_} flag has been defined in {\ufn \dots/config.h}.
756
757 When compiling the generated C code you will need:
758 \begin{enumerate}
759 \item
760 The include directory where the files from {\ufn \dots/c-lib/inc/} have been installed into in your include path so the C sources can include the library header files.
761 The header files should be included with statements like {\C \#include <snacc/c/asn-incl.h>} and your C compiler should be supplied with {\ufn -I/usr/local/include} in case snacc got installed under {\ufn /usr/local/}.
762 \item
763 to link with the correct C ASN.1 runtime library, depending on the buffer type you choose.
764 In case snacc got installed under {\ufn /usr/local/}, your linker may need to be supplied with {\ufn -L/usr/local/lib} and one of {\ufn -lasn1cebuf}, {\ufn -lasn1cmbuf} or {\ufn -lasn1csbuf} as arguments.
765 \item
766 to link with the math library ({\ufn -lm}), since the ASN.1 REAL type's encode and decode routine use some math routines.
767 \end{enumerate}
768
769 See the example in {\ufn \dots/c-examples/simple/} for a complete
770 example. The makefile and main routines are probably the most
771 important. There are several other examples in the
772 {\ufn \dots/c-examples/} directory.