]>
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