blob: 745919486d942d73c58c0363b7294cdd1bb9593f [file] [log] [blame]
Lev Walkin27fd0b62007-08-27 23:57:45 +00001#!/usr/bin/env perl
Lev Walkinf15320b2004-06-03 03:38:44 +00002
3#
4# $Id$
5# $Author$
6#
Lev Walkin27fd0b62007-08-27 23:57:45 +00007# Simple tool to fetch the ASN.1 specifications from the given set of RFC files.
Lev Walkinf15320b2004-06-03 03:38:44 +00008#
9
10
11my $inasn = 0; # Are we inside ASN.1 grammar?
12my $found = 0;
Lev Walkina2bf7242004-09-07 06:36:35 +000013my $currentFname = '';
Lev Walkinf15320b2004-06-03 03:38:44 +000014
15if(-t STDIN && $#ARGV == -1) {
16 print STDERR "Rip ASN.1 specification from RFC file\n";
17 print STDERR "Usage: $0 <rfc-file.txt> ...\n";
18 print STDERR "Usage: <someprog> | $0\n";
19 exit(1);
20}
21
22while(<>) {
23 #
24 # Strip RFC page delimiters.
25 #
26 next if /^[A-Z].*\[Page [0-9]+\]$/;
27 next if /^ $/;
28 next if /^RFC [0-9].*[0-9]+$/;
29
30 if($inasn == 0) {
31 #
32 # The least correct way to find the start of ASN
Lev Walkin8c85f2a2006-09-09 11:26:09 +000033 # definition. That is, to ask a user.
Lev Walkinf15320b2004-06-03 03:38:44 +000034 #
Lev Walkind7f237b2005-03-17 22:43:48 +000035 if(/^[ \t]*END[ \t]*(--.*)?$/) {
Lev Walkinf15320b2004-06-03 03:38:44 +000036 print STDERR
37 "Missed an ASN.1 grammar before line ". $. ."?\n";
38 exit(1);
39 }
40
Lev Walkind7f237b2005-03-17 22:43:48 +000041 my $modName = ''; # ASN.1 module name
Lev Walkinf15320b2004-06-03 03:38:44 +000042 my $rfcid = '';
43 $rfcid = $1 . '-' if($ARGV =~ /([a-z0-9]+)/i);
44
Lev Walkinc2c34922006-05-04 17:35:24 +000045 if(/^[ \t]*([A-Z][A-Za-z0-9-]*).*DEFINITIONS.*::=/) {
Lev Walkind7f237b2005-03-17 22:43:48 +000046 $modName = $1;
47 $currentFname = $rfcid . $modName . ".asn1";
Lev Walkinf15320b2004-06-03 03:38:44 +000048 $inasn = 1;
Lev Walkind7f237b2005-03-17 22:43:48 +000049 } elsif(/^[ \t]*([A-Z][A-Za-z0-9-]*).*{[ \t]*iso/
50 || /^[ \t]*{[ \t]*iso/) {
51 $modName = $1;
52 unless(length($modName)) {
53 next unless $prevLine =~
54 /^[ \t]*([A-Z][A-Za-z0-9-]*)[ \t]*$/;
55 $modName = $1;
56 }
57 $currentFname = $rfcid . $modName . ".asn1";
Lev Walkinf15320b2004-06-03 03:38:44 +000058 my @a = ($_);
59 my $i;
60 for($i = 0; $i < 8; $i++) {
61 $_ = <>;
62 push(@a, $_);
63 if(/DEFINITIONS/) {
64 $_ = join('', @a);
65 $inasn = 1;
66 last;
67 }
68 }
69 next unless $inasn;
Lev Walkin8c85f2a2006-09-09 11:26:09 +000070 } elsif(/^\s*DEFINITIONS\s*$/
71 && $prevLine =~ /^\s*([A-Z][A-Za-z0-9-]*)\s*{[0-9a-z)( -]+}\s*$/) {
72 $_ = $prevLine . $prevComments . $_;
73 $modName = $1;
74 $currentFname = $rfcid . $modName. ".asn1";
75 $inasn = 1;
Lev Walkinf15320b2004-06-03 03:38:44 +000076 } else {
Lev Walkin8c85f2a2006-09-09 11:26:09 +000077 if(/^[ \t]*--/) {
78 $prevComments .= $_;
79 } else {
80 $prevComments = '';
81 $prevLine = $_;
82 }
Lev Walkinf15320b2004-06-03 03:38:44 +000083 next;
84 }
85
Lev Walkind7f237b2005-03-17 22:43:48 +000086 print STDERR "Found $modName at line $.\n=> Saving as $currentFname\n";
Lev Walkina2bf7242004-09-07 06:36:35 +000087 open(O, "> $currentFname") or die "Can't open $currentFname";
88 select(O);
89
Lev Walkinf15320b2004-06-03 03:38:44 +000090 $found++;
91 print "\n";
92 print "-- \n";
Lev Walkina2bf7242004-09-07 06:36:35 +000093 print "-- ASN.1 module found by $0 in $ARGV at line " . $. . "\n";
Lev Walkinf15320b2004-06-03 03:38:44 +000094 print "-- \n";
95 print "\n";
96 }
97
Lev Walkind7f237b2005-03-17 22:43:48 +000098 if(/^[ \t]*END[ \t]*(--.*)?$/) {
Lev Walkina2bf7242004-09-07 06:36:35 +000099 print;
Lev Walkinf15320b2004-06-03 03:38:44 +0000100 select(STDOUT);
101 close(O);
102 $inasn = 0;
Lev Walkina2bf7242004-09-07 06:36:35 +0000103 next;
Lev Walkinf15320b2004-06-03 03:38:44 +0000104 }
Lev Walkina2bf7242004-09-07 06:36:35 +0000105
106 #
107 # The following clauses are primarily designed to make
108 # asn1c command-line easier (i.e., to avoid "-ftypes88").
109 # You may want to get rid of them if you're doing generic
110 # ASN.1 extraction and do not want to alter the ASN.1 specs.
111 #
112 if(
Lev Walkind7f237b2005-03-17 22:43:48 +0000113/^([ \t]*)((UniversalString|BMPString|UTF8String)\s+::=\s+\[[A-Z]+\s\d+\]\sIMPLICIT\sOCTET\sSTRING)(.*)$/ms
Lev Walkina2bf7242004-09-07 06:36:35 +0000114 ) {
115 print "\n-- Legacy redefinition of $3 removed by $0:\n";
116 print "$1-- $2 -- $4";
117 next;
118 } elsif(/delete following line if \"new\" types are supported/) {
119 print;
120 print "/* Legacy stuff deleted by $0:\n";
121 $_ = <>;
122 print;
123 print " */\n";
124 next;
125 }
126
127
128 print; # Dump the ASN.1 module line out.
Lev Walkinf15320b2004-06-03 03:38:44 +0000129}
130
Lev Walkina2bf7242004-09-07 06:36:35 +0000131die "No ASN.1 modules found\n" unless $found;