]>
git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/compiler/core/recursive.c
2 * compiler/core/recursive.c - finds and marks the recursive types in a module.
5 * prints msgs for infinitely recursive types (ie recursive component
6 * is not OPTIONAL, nor a CHOICE elmt, nor a SET OF nor a SEQ OF elmt.
7 * (OPTIONALs can be left out, CHOICE elements have alternatives (hopefully),
8 * and SET OF and SEQUENCE OF values can have zero elements)
10 * prints msg for recursive types that hold no real information
11 * Foo ::= SET OF Foo (sets of sets of .... of empty sets)
13 * finds bogus recursive types (hold no info) (same as above)
20 * Copyright (C) 1991, 1992 Michael Sample
21 * and the University of British Columbia
23 * This program is free software; you can redistribute it and/or modify
24 * it under the terms of the GNU General Public License as published by
25 * the Free Software Foundation; either version 2 of the License, or
26 * (at your option) any later version.
28 * $Header: /cvs/Darwin/Security/SecuritySNACCRuntime/compiler/core/recursive.c,v 1.1 2001/06/20 21:27:58 dmitch Exp $
29 * $Log: recursive.c,v $
30 * Revision 1.1 2001/06/20 21:27:58 dmitch
31 * Adding missing snacc compiler files.
33 * Revision 1.1.1.1 1999/03/16 18:06:52 aram
34 * Originals from SMIME Free Library.
36 * Revision 1.3 1995/07/25 19:41:43 rj
37 * changed `_' to `-' in file names.
39 * Revision 1.2 1994/09/01 00:43:10 rj
40 * snacc_config.h removed; recursive.h includet.
42 * Revision 1.1 1994/08/28 09:49:35 rj
43 * first check-in. for a list of changes to the snacc-1.1 distribution please refer to the ChangeLog.
50 #include "asn1module.h"
51 #include "recursive.h"
52 #include "snacc-util.h"
54 void MkRecTypeDef
PROTO ((Module
*m
, TypeDef
*td
));
56 void MkRecType
PROTO ((Module
*m
, TypeDef
*td
,Type
*t
, int optional
, int empty
));
60 MarkRecursiveTypes
PARAMS ((m
),
65 /* first set all typedef as un-visited */
66 FOR_EACH_LIST_ELMT (td
, m
->typeDefs
)
72 FOR_EACH_LIST_ELMT (td
, m
->typeDefs
)
76 } /* MarkRecursiveTypes */
81 MkRecTypeDef
PARAMS ((m
, td
),
85 MkRecType (m
, td
, td
->type
, 0, 1);
91 * cruise through aggregate types and type refs looking for
92 * a type ref to the original type def, td. If is a ref to
93 * the td, then mark the td as recusive.
95 * the optional flag is set if the current type branch is
96 * optional via an OPTIONAL SET/SEQ elmt, CHOICE elmt, SET OF elmt
99 * the empty flag is initially TRUE and remains true until a
100 * non-type reference type is encountered
103 MkRecType
PARAMS ((m
, td
, t
, optional
, empty
),
113 switch (t
->basicType
->choiceId
)
115 case BASICTYPE_CHOICE
:
116 if (AsnListCount (t
->basicType
->a
.choice
) > 1)
121 FOR_EACH_LIST_ELMT (e
, t
->basicType
->a
.choice
)
123 MkRecType (m
, td
, e
->type
, optional
, empty
);
128 case BASICTYPE_SEQUENCE
:
131 FOR_EACH_LIST_ELMT (e
, t
->basicType
->a
.set
)
133 newOptional
= optional
|| (e
->type
->optional
) ||
134 (e
->type
->defaultVal
!= NULL
);
135 MkRecType (m
, td
, e
->type
, newOptional
, empty
);
139 case BASICTYPE_SETOF
:
140 case BASICTYPE_SEQUENCEOF
:
141 empty
= 0; /* since an empty set is actual data */
142 optional
= 1; /* since SET OF and SEQ OF's can be empty */
143 MkRecType (m
, td
, t
->basicType
->a
.setOf
, optional
, empty
);
146 case BASICTYPE_LOCALTYPEREF
:
147 case BASICTYPE_IMPORTTYPEREF
:
150 * check if ref to original type def & mark recursive if so.
152 /* if ((strcmp (t->basicType->a.localTypeRef->typeName, td->definedName) == 0) && (t->basicType->a.localTypeRef->module == m))
153 easier to just check ptrs!
155 if (t
->basicType
->a
.localTypeRef
->link
== td
)
160 PrintErrLoc (m
->asn1SrcFileName
, td
->type
->lineNo
);
161 fprintf (stderr
,"WARNING: Type \"%s\" appears to be infinitely recursive and can hold no values! (circular type references)\n", td
->definedName
);
165 PrintErrLoc (m
->asn1SrcFileName
, t
->lineNo
);
166 fprintf (stderr
,"WARNING: Type \"%s\" appears to be infinitely recursive! (infinitely sized values)\n", td
->definedName
);
171 * else follow this type reference if we aren't in it already
172 * (ie another recursive type in td)
174 else if (t
->basicType
->a
.localTypeRef
->link
->tmpRefCount
== 0)
177 * mark this typedef as 'entered' to
178 * detect when looping in a recusive type that is contained
179 * in the original td (use tmpRefCount)
181 t
->basicType
->a
.localTypeRef
->link
->tmpRefCount
= 1;
183 newOptional
= optional
|| (t
->optional
) || (t
->defaultVal
!= NULL
);
184 MkRecType (m
, td
, t
->basicType
->a
.localTypeRef
->link
->type
, newOptional
, empty
);
187 * un-mark this type since finished with it
188 * for recursive ref's to td
190 t
->basicType
->a
.localTypeRef
->link
->tmpRefCount
= 0;
195 * default: other types are not aggregate and
196 * do not make recursive refs - they can be ignored