blob: d9c8c861c903c013c78ef34a79c0e94cd3ca21f3 [file] [log] [blame]
Lev Walkin27fd0b62007-08-27 23:57:45 +00001#!/usr/bin/env perl
Lev Walkinf15320b2004-06-03 03:38:44 +00002#
Lev Walkin98e9b932013-10-24 01:36:43 -07003# Extract the ASN.1 module text from the given set of RFC files.
Lev Walkinf15320b2004-06-03 03:38:44 +00004#
5
6
7my $inasn = 0; # Are we inside ASN.1 grammar?
8my $found = 0;
Lev Walkina2bf7242004-09-07 06:36:35 +00009my $currentFname = '';
Lev Walkinf15320b2004-06-03 03:38:44 +000010
11if(-t STDIN && $#ARGV == -1) {
Lev Walkin8b3b3d82014-09-07 07:13:16 -070012 print STDERR "Extract the ASN.1 specification from the RFC file(s).\n";
13 print STDERR "Usage 1: $0 <rfc-file.txt> ...\n";
14 print STDERR "Usage 2: <someprog> | $0\n";
Lev Walkinf15320b2004-06-03 03:38:44 +000015 exit(1);
16}
17
18while(<>) {
19 #
20 # Strip RFC page delimiters.
21 #
22 next if /^[A-Z].*\[Page [0-9]+\]$/;
23 next if /^ $/;
24 next if /^RFC [0-9].*[0-9]+$/;
25
26 if($inasn == 0) {
27 #
28 # The least correct way to find the start of ASN
Lev Walkin8c85f2a2006-09-09 11:26:09 +000029 # definition. That is, to ask a user.
Lev Walkinf15320b2004-06-03 03:38:44 +000030 #
Lev Walkind7f237b2005-03-17 22:43:48 +000031 if(/^[ \t]*END[ \t]*(--.*)?$/) {
Lev Walkinf15320b2004-06-03 03:38:44 +000032 print STDERR
33 "Missed an ASN.1 grammar before line ". $. ."?\n";
34 exit(1);
35 }
36
Lev Walkind7f237b2005-03-17 22:43:48 +000037 my $modName = ''; # ASN.1 module name
Lev Walkinf15320b2004-06-03 03:38:44 +000038 my $rfcid = '';
39 $rfcid = $1 . '-' if($ARGV =~ /([a-z0-9]+)/i);
40
Lev Walkinc2c34922006-05-04 17:35:24 +000041 if(/^[ \t]*([A-Z][A-Za-z0-9-]*).*DEFINITIONS.*::=/) {
Lev Walkind7f237b2005-03-17 22:43:48 +000042 $modName = $1;
43 $currentFname = $rfcid . $modName . ".asn1";
Lev Walkinf15320b2004-06-03 03:38:44 +000044 $inasn = 1;
Lev Walkind7f237b2005-03-17 22:43:48 +000045 } elsif(/^[ \t]*([A-Z][A-Za-z0-9-]*).*{[ \t]*iso/
46 || /^[ \t]*{[ \t]*iso/) {
47 $modName = $1;
48 unless(length($modName)) {
49 next unless $prevLine =~
50 /^[ \t]*([A-Z][A-Za-z0-9-]*)[ \t]*$/;
51 $modName = $1;
52 }
53 $currentFname = $rfcid . $modName . ".asn1";
Lev Walkinf15320b2004-06-03 03:38:44 +000054 my @a = ($_);
55 my $i;
56 for($i = 0; $i < 8; $i++) {
57 $_ = <>;
58 push(@a, $_);
59 if(/DEFINITIONS/) {
60 $_ = join('', @a);
61 $inasn = 1;
62 last;
63 }
64 }
65 next unless $inasn;
Lev Walkin8c85f2a2006-09-09 11:26:09 +000066 } elsif(/^\s*DEFINITIONS\s*$/
67 && $prevLine =~ /^\s*([A-Z][A-Za-z0-9-]*)\s*{[0-9a-z)( -]+}\s*$/) {
68 $_ = $prevLine . $prevComments . $_;
69 $modName = $1;
70 $currentFname = $rfcid . $modName. ".asn1";
71 $inasn = 1;
Lev Walkinf15320b2004-06-03 03:38:44 +000072 } else {
Lev Walkin8c85f2a2006-09-09 11:26:09 +000073 if(/^[ \t]*--/) {
74 $prevComments .= $_;
75 } else {
76 $prevComments = '';
77 $prevLine = $_;
78 }
Lev Walkinf15320b2004-06-03 03:38:44 +000079 next;
80 }
81
Lev Walkind7f237b2005-03-17 22:43:48 +000082 print STDERR "Found $modName at line $.\n=> Saving as $currentFname\n";
Lev Walkina2bf7242004-09-07 06:36:35 +000083 open(O, "> $currentFname") or die "Can't open $currentFname";
84 select(O);
85
Lev Walkinf15320b2004-06-03 03:38:44 +000086 $found++;
87 print "\n";
88 print "-- \n";
Lev Walkina2bf7242004-09-07 06:36:35 +000089 print "-- ASN.1 module found by $0 in $ARGV at line " . $. . "\n";
Lev Walkinf15320b2004-06-03 03:38:44 +000090 print "-- \n";
91 print "\n";
92 }
93
Lev Walkind7f237b2005-03-17 22:43:48 +000094 if(/^[ \t]*END[ \t]*(--.*)?$/) {
Lev Walkina2bf7242004-09-07 06:36:35 +000095 print;
Lev Walkinf15320b2004-06-03 03:38:44 +000096 select(STDOUT);
97 close(O);
98 $inasn = 0;
Lev Walkina2bf7242004-09-07 06:36:35 +000099 next;
Lev Walkinf15320b2004-06-03 03:38:44 +0000100 }
Lev Walkina2bf7242004-09-07 06:36:35 +0000101
102 #
103 # The following clauses are primarily designed to make
104 # asn1c command-line easier (i.e., to avoid "-ftypes88").
105 # You may want to get rid of them if you're doing generic
106 # ASN.1 extraction and do not want to alter the ASN.1 specs.
107 #
108 if(
Lev Walkind7f237b2005-03-17 22:43:48 +0000109/^([ \t]*)((UniversalString|BMPString|UTF8String)\s+::=\s+\[[A-Z]+\s\d+\]\sIMPLICIT\sOCTET\sSTRING)(.*)$/ms
Lev Walkina2bf7242004-09-07 06:36:35 +0000110 ) {
111 print "\n-- Legacy redefinition of $3 removed by $0:\n";
112 print "$1-- $2 -- $4";
113 next;
114 } elsif(/delete following line if \"new\" types are supported/) {
115 print;
116 print "/* Legacy stuff deleted by $0:\n";
117 $_ = <>;
118 print;
119 print " */\n";
120 next;
121 }
122
123
124 print; # Dump the ASN.1 module line out.
Lev Walkinf15320b2004-06-03 03:38:44 +0000125}
126
Lev Walkina2bf7242004-09-07 06:36:35 +0000127die "No ASN.1 modules found\n" unless $found;