blob: 5a57f2d037556741ba96d5c5136b6241489b787d [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 = '';
Lev Walkine0d321a2014-09-11 01:28:57 -070039 $rfcid = $1 . '-' if($ARGV =~ /([a-z0-9]+)\.[^.]+$/i);
Lev Walkinf15320b2004-06-03 03:38:44 +000040
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 Walkin26303bd2016-03-14 02:30:52 -070045 } elsif(/^[ \t]*([A-Z][A-Za-z0-9-]*).*{[ \t]*(?:joint-)?iso/
46 || /^[ \t]*{[ \t]*(?:joint-)?iso/) {
Wim Lewisd9d36f82014-03-12 13:52:08 -070047 my @a = ($_);
Lev Walkind7f237b2005-03-17 22:43:48 +000048 $modName = $1;
49 unless(length($modName)) {
50 next unless $prevLine =~
51 /^[ \t]*([A-Z][A-Za-z0-9-]*)[ \t]*$/;
52 $modName = $1;
Wim Lewisd9d36f82014-03-12 13:52:08 -070053 unshift(@a, $prevLine);
Lev Walkind7f237b2005-03-17 22:43:48 +000054 }
55 $currentFname = $rfcid . $modName . ".asn1";
Lev Walkinf15320b2004-06-03 03:38:44 +000056 my $i;
57 for($i = 0; $i < 8; $i++) {
58 $_ = <>;
59 push(@a, $_);
60 if(/DEFINITIONS/) {
61 $_ = join('', @a);
62 $inasn = 1;
63 last;
64 }
65 }
66 next unless $inasn;
Lev Walkin8c85f2a2006-09-09 11:26:09 +000067 } elsif(/^\s*DEFINITIONS\s*$/
68 && $prevLine =~ /^\s*([A-Z][A-Za-z0-9-]*)\s*{[0-9a-z)( -]+}\s*$/) {
69 $_ = $prevLine . $prevComments . $_;
70 $modName = $1;
71 $currentFname = $rfcid . $modName. ".asn1";
72 $inasn = 1;
Lev Walkinf15320b2004-06-03 03:38:44 +000073 } else {
Lev Walkin8c85f2a2006-09-09 11:26:09 +000074 if(/^[ \t]*--/) {
75 $prevComments .= $_;
76 } else {
77 $prevComments = '';
78 $prevLine = $_;
79 }
Lev Walkinf15320b2004-06-03 03:38:44 +000080 next;
81 }
82
Lev Walkind7f237b2005-03-17 22:43:48 +000083 print STDERR "Found $modName at line $.\n=> Saving as $currentFname\n";
Lev Walkina2bf7242004-09-07 06:36:35 +000084 open(O, "> $currentFname") or die "Can't open $currentFname";
85 select(O);
86
Lev Walkinf15320b2004-06-03 03:38:44 +000087 $found++;
88 print "\n";
89 print "-- \n";
Lev Walkina2bf7242004-09-07 06:36:35 +000090 print "-- ASN.1 module found by $0 in $ARGV at line " . $. . "\n";
Lev Walkinf15320b2004-06-03 03:38:44 +000091 print "-- \n";
92 print "\n";
93 }
94
Lev Walkind7f237b2005-03-17 22:43:48 +000095 if(/^[ \t]*END[ \t]*(--.*)?$/) {
Lev Walkina2bf7242004-09-07 06:36:35 +000096 print;
Lev Walkinf15320b2004-06-03 03:38:44 +000097 select(STDOUT);
98 close(O);
99 $inasn = 0;
Lev Walkina2bf7242004-09-07 06:36:35 +0000100 next;
Lev Walkinf15320b2004-06-03 03:38:44 +0000101 }
Lev Walkina2bf7242004-09-07 06:36:35 +0000102
103 #
Lev Walkine0d321a2014-09-11 01:28:57 -0700104 # The following clauses are primarily designed to simplify
105 # asn1c tool behavior.
Lev Walkina2bf7242004-09-07 06:36:35 +0000106 # You may want to get rid of them if you're doing generic
Lev Walkine0d321a2014-09-11 01:28:57 -0700107 # ASN.1 extraction and do not want to alter the ASN.1 specs at all.
Lev Walkina2bf7242004-09-07 06:36:35 +0000108 #
109 if(
Lev Walkind7f237b2005-03-17 22:43:48 +0000110/^([ \t]*)((UniversalString|BMPString|UTF8String)\s+::=\s+\[[A-Z]+\s\d+\]\sIMPLICIT\sOCTET\sSTRING)(.*)$/ms
Lev Walkina2bf7242004-09-07 06:36:35 +0000111 ) {
112 print "\n-- Legacy redefinition of $3 removed by $0:\n";
113 print "$1-- $2 -- $4";
114 next;
115 } elsif(/delete following line if \"new\" types are supported/) {
116 print;
Lev Walkine0d321a2014-09-11 01:28:57 -0700117 print "/* Legacy constructs deleted by $0:\n";
Lev Walkina2bf7242004-09-07 06:36:35 +0000118 $_ = <>;
119 print;
120 print " */\n";
121 next;
122 }
123
124
125 print; # Dump the ASN.1 module line out.
Lev Walkinf15320b2004-06-03 03:38:44 +0000126}
127
Lev Walkina2bf7242004-09-07 06:36:35 +0000128die "No ASN.1 modules found\n" unless $found;