blob: ecf7573266784b8555916666e59d2141f6899b30 [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
34 # definition.
35 #
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 Walkinf15320b2004-06-03 03:38:44 +000071 } else {
Lev Walkind7f237b2005-03-17 22:43:48 +000072 $prevLine = $_;
Lev Walkinf15320b2004-06-03 03:38:44 +000073 next;
74 }
75
Lev Walkind7f237b2005-03-17 22:43:48 +000076 print STDERR "Found $modName at line $.\n=> Saving as $currentFname\n";
Lev Walkina2bf7242004-09-07 06:36:35 +000077 open(O, "> $currentFname") or die "Can't open $currentFname";
78 select(O);
79
Lev Walkinf15320b2004-06-03 03:38:44 +000080 $found++;
81 print "\n";
82 print "-- \n";
Lev Walkina2bf7242004-09-07 06:36:35 +000083 print "-- ASN.1 module found by $0 in $ARGV at line " . $. . "\n";
Lev Walkinf15320b2004-06-03 03:38:44 +000084 print "-- \n";
85 print "\n";
86 }
87
Lev Walkind7f237b2005-03-17 22:43:48 +000088 if(/^[ \t]*END[ \t]*(--.*)?$/) {
Lev Walkina2bf7242004-09-07 06:36:35 +000089 print;
Lev Walkinf15320b2004-06-03 03:38:44 +000090 select(STDOUT);
91 close(O);
92 $inasn = 0;
Lev Walkina2bf7242004-09-07 06:36:35 +000093 next;
Lev Walkinf15320b2004-06-03 03:38:44 +000094 }
Lev Walkina2bf7242004-09-07 06:36:35 +000095
96 #
97 # The following clauses are primarily designed to make
98 # asn1c command-line easier (i.e., to avoid "-ftypes88").
99 # You may want to get rid of them if you're doing generic
100 # ASN.1 extraction and do not want to alter the ASN.1 specs.
101 #
102 if(
Lev Walkind7f237b2005-03-17 22:43:48 +0000103/^([ \t]*)((UniversalString|BMPString|UTF8String)\s+::=\s+\[[A-Z]+\s\d+\]\sIMPLICIT\sOCTET\sSTRING)(.*)$/ms
Lev Walkina2bf7242004-09-07 06:36:35 +0000104 ) {
105 print "\n-- Legacy redefinition of $3 removed by $0:\n";
106 print "$1-- $2 -- $4";
107 next;
108 } elsif(/delete following line if \"new\" types are supported/) {
109 print;
110 print "/* Legacy stuff deleted by $0:\n";
111 $_ = <>;
112 print;
113 print " */\n";
114 next;
115 }
116
117
118 print; # Dump the ASN.1 module line out.
Lev Walkinf15320b2004-06-03 03:38:44 +0000119}
120
Lev Walkina2bf7242004-09-07 06:36:35 +0000121die "No ASN.1 modules found\n" unless $found;