blob: 4a800f89a5b098d24830db3372a147debd4f6edd [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#!/usr/bin/perl
2
3#
4# $Id$
5# $Author$
6#
7# Simple tool that fetches the ASN.1 specifications from the
8# given set of RFC files.
9#
10
11
12my $inasn = 0; # Are we inside ASN.1 grammar?
13my $found = 0;
Lev Walkina2bf7242004-09-07 06:36:35 +000014my $currentFname = '';
Lev Walkinf15320b2004-06-03 03:38:44 +000015
16if(-t STDIN && $#ARGV == -1) {
17 print STDERR "Rip ASN.1 specification from RFC file\n";
18 print STDERR "Usage: $0 <rfc-file.txt> ...\n";
19 print STDERR "Usage: <someprog> | $0\n";
20 exit(1);
21}
22
23while(<>) {
24 #
25 # Strip RFC page delimiters.
26 #
27 next if /^[A-Z].*\[Page [0-9]+\]$/;
28 next if /^ $/;
29 next if /^RFC [0-9].*[0-9]+$/;
30
31 if($inasn == 0) {
32 #
33 # The least correct way to find the start of ASN
Lev Walkin8c85f2a2006-09-09 11:26:09 +000034 # definition. That is, to ask a user.
Lev Walkinf15320b2004-06-03 03:38:44 +000035 #
Lev Walkind7f237b2005-03-17 22:43:48 +000036 if(/^[ \t]*END[ \t]*(--.*)?$/) {
Lev Walkinf15320b2004-06-03 03:38:44 +000037 print STDERR
38 "Missed an ASN.1 grammar before line ". $. ."?\n";
39 exit(1);
40 }
41
Lev Walkind7f237b2005-03-17 22:43:48 +000042 my $modName = ''; # ASN.1 module name
Lev Walkinf15320b2004-06-03 03:38:44 +000043 my $rfcid = '';
44 $rfcid = $1 . '-' if($ARGV =~ /([a-z0-9]+)/i);
45
Lev Walkinc2c34922006-05-04 17:35:24 +000046 if(/^[ \t]*([A-Z][A-Za-z0-9-]*).*DEFINITIONS.*::=/) {
Lev Walkind7f237b2005-03-17 22:43:48 +000047 $modName = $1;
48 $currentFname = $rfcid . $modName . ".asn1";
Lev Walkinf15320b2004-06-03 03:38:44 +000049 $inasn = 1;
Lev Walkind7f237b2005-03-17 22:43:48 +000050 } elsif(/^[ \t]*([A-Z][A-Za-z0-9-]*).*{[ \t]*iso/
51 || /^[ \t]*{[ \t]*iso/) {
52 $modName = $1;
53 unless(length($modName)) {
54 next unless $prevLine =~
55 /^[ \t]*([A-Z][A-Za-z0-9-]*)[ \t]*$/;
56 $modName = $1;
57 }
58 $currentFname = $rfcid . $modName . ".asn1";
Lev Walkinf15320b2004-06-03 03:38:44 +000059 my @a = ($_);
60 my $i;
61 for($i = 0; $i < 8; $i++) {
62 $_ = <>;
63 push(@a, $_);
64 if(/DEFINITIONS/) {
65 $_ = join('', @a);
66 $inasn = 1;
67 last;
68 }
69 }
70 next unless $inasn;
Lev Walkin8c85f2a2006-09-09 11:26:09 +000071 } elsif(/^\s*DEFINITIONS\s*$/
72 && $prevLine =~ /^\s*([A-Z][A-Za-z0-9-]*)\s*{[0-9a-z)( -]+}\s*$/) {
73 $_ = $prevLine . $prevComments . $_;
74 $modName = $1;
75 $currentFname = $rfcid . $modName. ".asn1";
76 $inasn = 1;
Lev Walkinf15320b2004-06-03 03:38:44 +000077 } else {
Lev Walkin8c85f2a2006-09-09 11:26:09 +000078 if(/^[ \t]*--/) {
79 $prevComments .= $_;
80 } else {
81 $prevComments = '';
82 $prevLine = $_;
83 }
Lev Walkinf15320b2004-06-03 03:38:44 +000084 next;
85 }
86
Lev Walkind7f237b2005-03-17 22:43:48 +000087 print STDERR "Found $modName at line $.\n=> Saving as $currentFname\n";
Lev Walkina2bf7242004-09-07 06:36:35 +000088 open(O, "> $currentFname") or die "Can't open $currentFname";
89 select(O);
90
Lev Walkinf15320b2004-06-03 03:38:44 +000091 $found++;
92 print "\n";
93 print "-- \n";
Lev Walkina2bf7242004-09-07 06:36:35 +000094 print "-- ASN.1 module found by $0 in $ARGV at line " . $. . "\n";
Lev Walkinf15320b2004-06-03 03:38:44 +000095 print "-- \n";
96 print "\n";
97 }
98
Lev Walkind7f237b2005-03-17 22:43:48 +000099 if(/^[ \t]*END[ \t]*(--.*)?$/) {
Lev Walkina2bf7242004-09-07 06:36:35 +0000100 print;
Lev Walkinf15320b2004-06-03 03:38:44 +0000101 select(STDOUT);
102 close(O);
103 $inasn = 0;
Lev Walkina2bf7242004-09-07 06:36:35 +0000104 next;
Lev Walkinf15320b2004-06-03 03:38:44 +0000105 }
Lev Walkina2bf7242004-09-07 06:36:35 +0000106
107 #
108 # The following clauses are primarily designed to make
109 # asn1c command-line easier (i.e., to avoid "-ftypes88").
110 # You may want to get rid of them if you're doing generic
111 # ASN.1 extraction and do not want to alter the ASN.1 specs.
112 #
113 if(
Lev Walkind7f237b2005-03-17 22:43:48 +0000114/^([ \t]*)((UniversalString|BMPString|UTF8String)\s+::=\s+\[[A-Z]+\s\d+\]\sIMPLICIT\sOCTET\sSTRING)(.*)$/ms
Lev Walkina2bf7242004-09-07 06:36:35 +0000115 ) {
116 print "\n-- Legacy redefinition of $3 removed by $0:\n";
117 print "$1-- $2 -- $4";
118 next;
119 } elsif(/delete following line if \"new\" types are supported/) {
120 print;
121 print "/* Legacy stuff deleted by $0:\n";
122 $_ = <>;
123 print;
124 print " */\n";
125 next;
126 }
127
128
129 print; # Dump the ASN.1 module line out.
Lev Walkinf15320b2004-06-03 03:38:44 +0000130}
131
Lev Walkina2bf7242004-09-07 06:36:35 +0000132die "No ASN.1 modules found\n" unless $found;